Client-Side Performance

In past articles, I've covered different ways to understand, analyze and improve the performance of your web applications. I've shown that between your network connections, server hardware, database design and HTTP server configuration, you can change and improve the performance of your web application—well, sort of. Web applications, when they first started, were dynamic only on the server side. Sure, they output HTML—and later, CSS and JavaScript—but the overwhelming majority of the processing and computation took place on the server.

This model, of course, has changed dramatically in the last decade, to such a degree that you now accurately can claim to be a web developer and work almost exclusively in HTML, CSS and JavaScript, with little or no server-side component. Entire MVC frameworks, such as Ember.js, Angular.js and React.js, assume that you'll be writing your application in JavaScript and provide you with the objects and infrastructure necessary for doing so.

If you're worried about the performance of your web application, you need to concern yourself not only with what happens on the server, but also with what happens in the browser. Some commercial performance-monitoring solutions already take this into account, allowing you to see how long it takes for elements to render, and then to execute, on your users' browsers. However, there is also no shortage of open-source tools available for you to check and improve the ways in which your client-side programs are executing.

This month, I'm concluding this exploration of web application performance with a survey of things to keep in mind, as well as tools that help ensure that you're actually doing what you should be.

Client-Side Considerations

Client-side code is written in JavaScript. The code, whether inline in <script> tags or retrieved from a remote server, executes whenever the browser's parser gets to that part of the page. If you have JavaScript at the top of the page, it'll be executed when the parser gets to it, potentially delaying the rendering of the rest of your page. By contrast, if your JavaScript is at the bottom, the parser will execute it only after parsing and rendering the rest of the page. This is why so many developers learned to put their JavaScript commands inside a "document-ready" callback function; in that way, the code was executed only once the entire page had been loaded.

Because so many modern web applications take place in JavaScript, the fact that you're often loading JavaScript from remote servers means that the time it takes to render a page depends not just on the server speed, the network bandwidth and the page's complexity, but also on the servers and networks serving such JavaScript, as well as those pages' complexity. As a result, it's generally considered to be good practice to load as many libraries as possible late in the game, at the bottom of your HTML page. That is, instead of having your <script> tags, whether local or remote, at the top of your page, you should put them at the bottom—unless it's vital to do otherwise.

Even better, you should consolidate your JavaScript files into a single file. This has a number of advantages. It means the user's browser needs to download a single file, rather than many of them. If you include all of the JavaScript needed on your site in a single file, it also means that the file needs to be loaded only a single time. On every subsequent page load, the JavaScript will be mentioned, but it won't be downloaded, because it'll already be cached in the browser's memory. You can make things even better, of course, by compressing that single JavaScript file. This turns out to be extremely effective, because compression algorithms work well with text, and especially with text that repeats itself, as happens with program code.

Better yet, you can run JavaScript code through a minimizer (or "minifier"), which removes comments, extraneous whitespace and anything else that isn't necessary for client-side programs to run. By minifying JavaScript files, combining the files and then compressing the resulting combination, you can dramatically reduce the size of the JavaScript being sent to the user's browser and ensure that it is loaded only once per visit to your website.

UglifyJS, for example, can be installed via npm:

npm install uglify-js -g

You can run it on a file with:

uglifyjs FILENAME

Although because that sends output to stdout, you'll likely want to redirect it to a file:

uglifyjs FILENAME > ugFILENAME.js

I took the JavaScript from my PhD dissertation software and ran it through both uglifyjs and gzip. The original 36KB file was 8.5KB after compression, but 6.0KB after uglifying and compression. Although you might scoff at the small size of a 36KB file in the modern world, the fact is that each file takes time, for both the browser and the server. The faster you can get it off your server and into the browser, the better.