This is the first article in a series about the Optimal User Experience, where I’ll discuss the value of Non-Blocking Pages.
The Problem
Hello. This. Is. My. Blocking. Page.
For better (simplicity) or for worse (user experience), HTML standards require, by default, that Script halts execution until loading and execution of said Script has completed. While this decision may be logical from an ease-of-development standpoint, it’s ultimately not in the best interest of the Optimal User Experience. After all, have you ever come across someone that enjoys waiting… for anything?
Demonstration
Here we’ve got a very basic HTML page with 5 DIVs, then 5 Scripts that update the background color of their associated DIV to green to indicate completion, followed by a stylesheet that sets the background of the body to blue. Simple enough, right? Let’s take a look.
Here are the initial renderings:
Now look at the final renderings:
Unlike my Conventional Blocking Web Page, my Non-Blocking Web Page produces a consistent user experience across both new and old browsers, including your favorite, IE6!
The Experience
My Web page was intentionally designed poorly to demonstrate, at a most basic level, what many users experience. In fact, my script resources have a hard-coded 2-second delay (server-side) to exaggerate the experience (Connection speeds and distance between servers being a major factor in real-world variance). As you can see from the images above, upon first render, there are two obvious differences:
- Stylesheet not loaded – Here, I’ve poorly designed my page, having included my stylesheet at the bottom, resulting in styles being applied only after all of the previous script blocks have completed loading and execution. More modern browsers are good about pre-fetching resources following the blocking scripts (to reduce load times), but their execution must still be deferred until prior scripts have completed, resulting in the above experience, even on modern browsers.
- Content not visible – I have a Script following each of my DIVs (ugly, huh?), preventing my user from seeing all of my content until each of my Scripts have loaded and executed. While my usage is exaggerated, this problem is surprisingly typical, though not always noticed by users on good connections. You certainly expect native Applications (be it PC or Mobile) to render in a timely manner, and despite what some may tell you, you should expect a similar level of experience from websites.
Better Code?
For those with experience in optimizing their pages, some of the first thoughts are to move my stylesheet(s) to the top (Problem 1 solved), and move all of my scripts to the bottom (Problem 2 solved); both good suggestions. What you might find, however, is that as applications grow, they tend to become more complex to manage while still retaining all of the best coding practices you know and love. Producing a well-optimized release is one thing, but retaining those optimizations over every release is another challenge entirely.
Native HTML Asynchronous Support
Script options include “defer” (load asynchronously, but defers execution) and “async” (load asynchronously and executes once loaded). In either case, these may not be supported by all browsers, providing not only an inconsistent experience across browsers, but also unnecessarily punishing users on legacy browsers, which happen to be the users with the greatest need for a better User Experience.
Asynchronous (Non-Blocking) Loading Patterns
While loaders go beyond the scope of this article, here’s a brief example.
<script>
require(“myscript.js”, function() { // asynchronous callback
// myscript.js is now available
});
</script>
There are a number of options out there when it comes to loaders. However, the top two I’d recommend are curl (based on the Asynchronous Module Definition pattern, and not to be confused with cURL) and RequireJS (based on the CommonJS pattern). Both are very worthy options. I personally prefer curl, as it’s a bit lighter, faster, more flexible, and its AMD pattern was recently adopted by jQuery. These loaders are very powerful, with many capabilities (a topic for another day), but at their core, are simply asynchronous resource loaders. Resources extend beyond simply Script, and can apply to virtually any Content Type.
Wrap Up
As with any performance tip, there is no one golden rule that negates the need for other performance considerations, and providing Non-Blocking Pages is no exception. What you can achieve with Non-Blocking Pages, however, is abstracting a good chunk of your performance management to an Asynchronous Loading Pattern, providing you a performance-first framework that you can rely on as your applications grow.




How about a way to load the godaddy site seal asynchronously. It is taking longer than the rest of my page combined.
Thanks,
Sean