Preload and Async Scripts For Faster Load Times

Keeping our products fast will always be one of our primary goals.  We love fast apps, and keep a lookout for ways to make them even faster.  That goes for initial load times as well as usage while inside the app.

Unfortunately JavaScript heavy apps fight against that goal.  For example, as additional features make their way into TimePanel, the amount of JavaScript we have to send across the network increases.  Caching helps, but has its own limits.  For example, the first time a user logs into TimePanel, they’re served the app’s CSS and JavaScript due to a cold cache.  Additionally, anytime we deploy updates, TimePanel’s CSS and JavaScript version numbers are bumped, forcing new versions to be loaded when a user logs in.  Those are two scenarios where caching doesn’t help and load times are increased.

Normally those kinds of circumstances may not be that bad, but since TimePanel’s JavaScript contain the entire app, its size introduces extra load time that users have to sit through.  That JavaScripts lock the browser’s UI thread until they’re downloaded and parsed compounds the matter.

Due to those problems, and how much we value speed, we sought out a way to minimize load times.  Enter HTML 5’s async script attribute coupled with a simple preloading technique.

JavaScript, HTML 5 Async, and Preloading

To give a brief background, there’s one main reason why JavaScripts, and their size, are problematic.  They block the browser’s UI thread, meaning that until a JavaScript is downloaded and parsed, nothing else happens in the browser.  That means a user could see nothing happening for some moment of time, perhaps even seconds, if a given JavaScript is big enough, or network latency is high enough.  This is why it’s always a good idea to keep JavaScript small, and if possible, serve them from a fast CDN (a CDN will typically provide better geolocation, speeding up file delivery to the user).

Another way to combat that is to leverage HTML 5’s async script attribute, and preloading.

HTML 5 introduced the async script attribute to mitigate the negative affects we just described related to JavaScript files.  With the async script attribute, developers have a way to declare that a script be loaded asynchronously so as to not block UI rendering or subsequent file downloads.  This provides a huge step forward toward maintaining a fast user experience while JavaScript files download to the user’s browser.

Additionally, preloading scripts is another way to achieve that.  By selectively inserting script tags in a non-interfering way before they’re needed, a user can transparently download and parse a JavaScript file, or other asset, behind the scenes.  This doesn’t speed up file loading per se, rather it off loads it in a way that’s transparent for the user.  This provides a perceived speed increase, and is exactly the kind of change we just deployed to help TimePanel load faster.

The Changes, and Before/After Results

The opportunity we saw was to load TimePanel’s CSS and JavaScript on the login page.  Since we didn’t want to just move the script load time from post-login to pre-login, we added the async script attribute to the CSS and JavaScript script tags.

Edit:  Thanks to Silvenga for correcting my use of the async attribute for CSS.  He correctly noted that async attributes only apply to script nodes, not link nodes.  I’ve since edited my post above to strike-through CSS references, and updated the following screen shot.

Async attribute.

Async attribute added to JavaScript file.

That keeps the login page rendering practically unaffected.  The JavaScript file downloads asynchronously while the user views the login page, or while entering their credentials.  Then, after the user logs in those files are reloaded, but this time via browser cache, resulting in a decrease in TimePanel’s load time, post-login.

Again, the download times of TimePanel’s JS using async on the login page isn’t faster than if it were downloaded otherwise.  But, since we’re doing it behind the scenes while the user is logging in it increases perceived performance of the app after login by being able to serve TimePanel’s JS from the browser cache instead of over the network.

And the results are noticeable.  Before and after results, taken from Chrome’s network waterfall, show the onload time went from 926ms to 646ms, a decrease of 283ms!

Before async and preloading - 926ms onload.

Before async and preloading – 926ms onload.

 

After async and preloading - 646ms onload.

After async and preloading – 646ms onload.

Conclusion

Speed is important, and HTML 5 and other modern techniques offer opportunities to speed up modern applications, despite growing feature sets and file sizes.

If JavaScript, or other performance-sensitive assets, are getting in the way of load times, consider applying the async script attribute to keep the user’s browser UI from locking up.  Also consider preloading scripts when possible to have scripts loaded and at the ready by the time user’s need them, without making the script’s download and parse time noticeable to the user.

 

This entry was posted in General. Bookmark the permalink.

4 Responses to Preload and Async Scripts For Faster Load Times

  1. Rohit says:

    Hi Guys,

    I tried loading the css on my site asynchronously, however it does not work. for eg

    google still says that it is not loading asynchronously.

    you can check my source and email me if you find anything. Thanks and regards,
    Rohit

    • mzarate says:

      Rohit,

      Sorry for the delay.

      Did you add the async property to your CSS tag? Just gave a quick check and it looks like you’ve ommitted that. Try adding that and test again.

  2. Silvenga says:

    HTML5 does not contain async in the spec for use with link nodes – only script nodes.

Leave a Reply to Silvenga Cancel reply

Your email address will not be published. Required fields are marked *