Boost your JavaScript application performance

Nicholas Zakas presents four JavaScript loading times to help improve your web application’s overall performance.

More and more it seems that web applications are running into performance problems that can often be traced back to JavaScript. It also seems we're having more problems with performance now despite JavaScript engines being much faster today compared to five years ago.

Perhaps older web applications benefited from a population with slower internet connections, or maybe no one thought that much about performance back then. It's easy to see why we're having problems now.

Always more power

Every leap in computing power is accompanied by a leap in the amount of computing power used by software. Software capabilities always grow to fill the processor and memory limits available. Web applications today use much more JavaScript than they used to, partially because JavaScript code is executed so much faster.

The same code that could take two whole seconds in Internet Explorer 7 can take less than a millisecond in Chrome. As a result, web applications keep adding more and more JavaScript, inextricably tying the application's experience to the JavaScript.

Every leap in computing power is accompanied by a leap in the amount of computing power used by software

It was common in my consulting practice to find web applications with over 1MB of required JavaScript (minified and un-gzipped). My first task was always to identify and eliminate any unnecessary or redundant JavaScript.

After that, left with the bare minimum (often still close to 1MB), I'd move on to the next phase: splitting up the various pieces of JavaScript by when they were loaded. This is when I developed the concept of the four JavaScript loading times.

A model to work with

The four JavaScript loading times is a mental model and a technical solution for using JavaScript in a web application. The mental model asks some questions about your JavaScript usage, such as when certain components are actually needed and what trigger tells you of their necessity.

The technical solution ensures the best possible user experience by providing points in time at which it's appropriate to load those JavaScript components. Perhaps the most important aspect of the four JavaScript loading times is in their ability to help you better understand your users' behaviour.

Loading Time 1: In the <head>

The first JavaScript loading time is in the <head> element of a page. Before web performance engineer Steve Souders informed the web development community that this wasn't a good idea, most web applications included JavaScript files at the top of the page along with CSS style sheets.

JavaScript loaded in the <head> prevents the document body rendering, which results in a blank page being displayed to the user while the browser waits to download and execute the JavaScript. As such, most web applications no longer load JavaScript in the <head>.

Unfortunately, there's a whole class of JavaScript that must be loaded early in the page in order to function correctly. Many types of analytics software that use JavaScript libraries to track user actions need to be loaded as early as possible in order to accurately track everything that happens during the lifecycle of the page. This may be for user-testing or advertising purposes, but the end result is that this code must be loaded in the <head>.

You can't completely forget about this first JavaScript loading time because of the type of software that requires it. Analytics are very important for web applications and so it's not possible or prudent to wait to load these libraries at a later time. In fact, it's the analytics software that makes it possible to determine what should be loaded in the other JavaScript loading times.

Loading Time 2: Bottom of <body>

Souders's recommendation is to load all JavaScript at the bottom of the <body> of a page, just before the </body> tag. Doing so allows the page to render completely before starting to download and execute JavaScript. This loading time is the best practice for getting JavaScript onto a page while it's being loaded.

If you use progressive enhancement, users are still able to interact with the page even before the JavaScript finishes loading. Doing so allows the time to interactivity (the time between the user requesting the page and being able to complete an action) to be as fast as possible.

It's the analytics software that makes it possible to determine what should be loaded

This is the area in which you should include all JavaScript that's necessary to be on the page at the page load time. What that typically means is any foundational JavaScript libraries (like jQuery, YUI, Backbone) plus any bootstrap code that prepares the application to be used. You may also want to load the JavaScript for whatever is the most common task that a user does immediately after page load.

Here are some examples:

  • Email application You may want to load code for reading an email as well as the email list.
  • Online store You may want to load any code related to search.
  • File sharing application You may want to load the code related to downloading and uploading.

The key to this loading time is to figure out the minimum amount of JavaScript code you need in order for the user to be successful with the first interaction on the application.

All of the JavaScript code to this point prevents the firing of the load event. The browser will appear to still be busy while the JavaScript code is being downloaded and executed.

Once the load event is fired, the browser no longer appears busy and visually appears to be loaded. The goal is always to make the transition from loading to loaded as quickly as possible.

This article first appeared in The JavaScript Handbook. You can buy your copy now for just £14.99

Loading Time 3: After load

The third JavaScript loading time occurs after the load event. This is the ideal time to start loading in additional JavaScript code that may be necessary for other tasks the user may do during the lifecycle of the application.

For instance, if your email application also offers chat, you may want to start downloading the chat code at this time. Since chat is a secondary feature in that case, it's OK to slightly delay the downloading of this code.

JavaScript code downloaded during this loading time is accomplished using the onload event handler and dynamic script loading. A simple example looks like this:

window.addEventListener(“load”, function() {
        var script = document.createElement(“script”);
        script.src = “/more/code.js”;
        document.body.insertBefore(script, document.body.firstChild);

We create a <script> element using the Document Object Model (DOM) and then add it to the page. This example uses a single file but you can load as many additional files as you would like. As the order of execution when loading multiple files isn't guaranteed, it's best if each file can live on its own.

This loading time is very effective when used with a progressively enhanced site as you can continue to load in more dynamic functionality, even as the page is already capable of serving the user needs. Large web applications frequently take advantage of this loading time.

Loading time 4: One Demand

On demand JavaScript loading can literally happen at any point in time based on how the user is interacting with the web application. It could be as simple as waiting until focus is set into the search box before loading search functionality, or watching for the mouse cursor to move towards an image before loading the zoomed-in view code.

The possibilities are vast for detecting are responding to user behaviour

You can also make it more complex by inferring what the user will do next based on the previous couple of actions. There are endless opportunities to get creative when loading JavaScript on demand, which makes it a very powerful option. Here are some options:

  • l Load JavaScript for search suggestions only once when the user sets the focus to the search box
  • Load JavaScript for a button only when the user moves the mouse within 200 pixels of it
  • Load JavaScript for the page footer only when the user scrolls down the page
  • Load JavaScript for image manipulation only when the user moves the mouse over an image

With the large number of JavaScript events available, the possibilities are vast for detecting and responding to user behaviour. Unfortunately, most web applications fail to take advantage of the fourth JavaScript loading time.

Nicholas Zakas presents four JavaScript loading times to help improve your web application's overall performanceIt doesn't take a lot of extra work but it can significantly reduce the amount of JavaScript code you need to download every time somebody loads the application.

All it takes is a little bit of thought about how people are using the application and a little bit of code (of course, analytics helps as well).

Using the Four Loading Times

While working with my clients, I encourage them to think of JavaScript functionality in terms of the four loading times and consider what has to appear immediately. What needs to be there before the load event? What has to be there after? What can we load based on what the user is doing?

Based on the four loading times, you can easily devise a plan for when each type of JavaScript has to be added onto the page. This plan is based on how users interact with your web application. Let your application users tell you what functionality is absolutely critical and at what point in time it will first be needed.

Finally, user analytics are often the missing piece to an important web performance puzzle, and the four JavaScript loading times use this data to make informed decisions about JavaScript that, in turn, will improve your app's performance.

Words: Nicholas Zakas

Nicholas Zakas is and expert in HTML5, CSS3, JavaScript, performance and architecture. Follow him on Twitter @slicknet. This article appeared originally in The JavaScript Handbook.