“Wait for me” said Spidermonkey

Spider Monkey

User experience is improved by fast loading pages. One technique is to load your javascripts at the bottom of the page. Javascript at the top of a page delays the downloading of images/css and delays the rendering of the page. Bikin Chiu points out how the delay can be longer on mobile devices, where download and execution is slower. Pushing javascript to the bottom of the page allows rendering to happen sooner, illustrated here.

Loading javascript last does have some drawbacks though. Your page might look loaded, but only work properly when all the javascript has executed. Lets look at some examples and another approach to work with this technique.

Example: twitter.com

On twitter’s redesigned homepage, clicking the login link causes a login form to pop-out - without loading another page.

twitter-login-good

A few times that I’ve clicked the login link ‘too quickly’ and instead of the nice pop-out form it loaded the old login page.

twitter-login-bad

This is frustrating because by being fast I’m penalised with a page reload. How do I know when it’s ok to click? The real answer is, not at least until DOMContentLoaded is fired…

net-panel-twitter

Any page that doesn’t cleanly degrade in the absence of javascript could have problems just after page rendering, momentarily behaving as if javascript is disabled.

Google’s approach with GMail is to wait until everything is loaded before showing the main interface.

google-loading

Facebook engineers tested a comparison between keeping the page blank until all javascript is loaded (similar to the GMail approach), and rendering a page earlier with a brief period when links may do nothing. They saw lower ‘usage statistics’ for the blank page option - hence settled on the render early approach.

A hybrid approach

What about rendering the page as quickly as possible, and defer handling clicks until all javascript has loaded? What if we ‘wait for Spidermonkey‘. I created a quick experiment, that registers a listener for click events, and replays the last click once the document is ready (all scripts loaded). In the twitter example this would mean a small delay but eventually showing the pop-out form.

Try it out in this exaggerated example. The link doesn’t respond until a 5 second delay. (I haven’t made this work in IE yet - can you? Fork this gist).

Is this better or worse? Seen as the window of misopportunity should be small, I think this is an improvement. Clicking a link will have a delay anyway, if we wait until javascript is loaded then the action will be the intended one, not some degradation. However I don’t like that users get no feedback, from the web page, or the browser, that something will happen, or when it will happen. What do you think?

Title photo: jcoterhals.


10 Comments

I think this is excellent Darragh. The delay or lack of feedback when the user clicks would only be noticable if your page (or their connection) is exceptionally slow, so I know I wouldn’t worry about it.

I was actually dealing with an issue like this recently where users could click “too quickly” and not fire some virtual page views for Google Analytics, this looks a really nice solution.

Posted by Peter McKenna at 10:11 am on 9 September, 2009.


The downside here is that you may end up replaying several clicks, resulting in some bizarre activity once the page is ready. I’ve seen people click, and click again if something expected doesn’t happen.

Posted by Murf at 11:39 am on 9 September, 2009.


Murf: Good point. For that reason I decided to only replay the most recent click in my example.

Posted by Darragh Curran at 11:41 am on 9 September, 2009.


Definitely an improvement, nice work!

Posted by Brian Armstrong at 1:08 pm on 9 September, 2009.


Darragh: aha, good idea!

Posted by Murf at 2:43 pm on 9 September, 2009.


Nope. It seems to work but it’s not working. I’m not going to read the whole page and see every little message telling me that it’s still loading.
Not a good idea in my eyes.

Posted by Tamim at 3:43 pm on 9 September, 2009.


Fair point Tamim. In real use I’d aim to have the page ready sub-second, and would avoid showing the ‘loading’ indicator. As far as the user is concerned the page is loaded, just if they click they’ll wait some milliseconds before an action happens. Have you any alternative suggestions for dealing with this issue?

Posted by Darragh Curran at 3:48 pm on 9 September, 2009.


Interesting idea. I run into this problem occasionally when using 1Password to log me into a site quickly. I’ve come to appreciate sites that don’t try to do anything fancy with their login forms.

Posted by Ab1e at 10:49 pm on 9 September, 2009.


How about a different approach: have one tiny “loading” script at the top of the page that adds a class ‘loading’ for example to the body (or html) element, as soon as possible. Then change this class to ‘loaded’ on DOM load, or after all other scripts (placed at the bottom of the markup) are loaded.

Now you can give all .loading elements a disabled look. You can even put yet another (small) script that would be the first one at the bottom of the page. It would fire after all content (and its DOM) is loaded, but before other scripts are loaded. It would temporarily disable all JavaScript links (they could be identified by a class).

The whole thing would work as follows:
1. [page starts loading]
2. (first script) Add ‘loading’ class to the body, resulting in a disabled view of JavaScript links
3. [page content loaded]
4. (second script) Really disable JavaScript links.
5. [main scripts loading]
6. (third script) Enable JavaScript links, remove ‘loading’ class (optionally add ‘loaded’ class).

You could probably skip step 2. and merge it with step 4.

Posted by Bartek at 1:48 am on 10 September, 2009.


This is a neat approach, and one worth taking seriously. I’m not sure though with the initial premise that degradation is something that needs fixing. With twitter, okay, you clicked the link too quickly … but you were still able to perform the action you were expecting - if that login page had received the same redesign as the home page, you would be oblivious to the fact that this wasn’t the expected behaviour.

The Google approach - basically to ignore degradation and keep you waiting is definitely more problematic for mobile / low bandwidth users, and I think your solution could be useful here … I might want some sort of visual feedback from the inactive links though to say ‘yup, we’re working on it’ … but maybe that’s just with your exaggerated example. If it were less than a second, I don’t think that’d be a problem.

Neat solution Darragh - and thanks for sharing,

David

Posted by David Horn at 8:19 pm on 10 September, 2009.


Post a Comment

We do web apps. E-mail e-mail address. Phone us at +353 1 672 9762. Post to 51 Wellington Quay, Dublin 2, Ireland.