Adam Stacoviak changelog.com/posts

headjs - The only script in your head

Head JS is a 2.3kb script that speeds up, simplifies and modernizes your site. Currently, Head JS is at an early alpha stage, but is promised to get more stable this week.

The HEAD section is the worst place to load scripts. It’s painfully slow. The more and the bigger the worse it gets. When you move your scripts to the end of the document you aren’t able to use HTML5 or CSS3 safely or you run into dependency problems.

That’s where Head JS comes into play.

So what’s the problem with loading on top?

A huge majority of the sites you visit everyday often have many SCRIPT tags in the HEAD section of the document.

Let’s take a peek at apple.com:

<script src="http://images.apple.com/global/scripts/lib/prototype.js" type="text/javascript" charset="utf-8"></script>
<script src="http://images.apple.com/global/scripts/lib/scriptaculous.js" type="text/javascript" charset="utf-8"></script>
<script src="http://images.apple.com/global/scripts/browserdetect.js" type="text/javascript" charset="utf-8"></script>
<script src="http://images.apple.com/global/scripts/apple_core.js" type="text/javascript" charset="utf-8"></script>
<script src="http://images.apple.com/global/scripts/search_decorator.js" type="text/javascript" charset="utf-8"></script>
<script src="http://images.apple.com/global/scripts/promomanager.js" type="text/javascript" charset="utf-8"></script>
<script src="http://images.apple.com/home/scripts/ticker.js" type="text/javascript" charset="utf-8"></script>
<script src="http://images.apple.com/home/scripts/promotracker.js" type="text/javascript" charset="utf-8"></script>

Apple is loading 11 scripts in total, but when you first hit the page you’ll have to wait for all these scripts to be loaded before the rest of the page gets rendered. In programming this is called blocking.

The total weight for the scripts on the Apple homepage comes in at 361.60kb.

apple.com-scripts

It can get even worse. Older browsers such as Firefox 3.5 load these scripts in sequence. The next script starts loading only after the previous script is fully loaded. This means that the first page render will be painfully slow.

A common solution to this is to move the script tags to the bottom of the document, just before the end of BODY tag.

So what’s the problem with loading on bottom?

When all scripts are included on the bottom of the page you’ll end up fighting with these issues:

  • HTML5 and CSS3 can’t be used and sad side effect is the treacherous FOUC (Flash of Unstyled Content). To avoid this ugly FOUC effect you need to load the script on top.
  • JavaScript organization gets hard and you can’t do scripting that depend on these scripts before they are included.

How does Head JS solve these problems?

The single best solution to these universal problems is to include Head JS on top of the page and load rest of the scripts with it and make it the only SCRIPT in your HEAD.

A small job with following benefits:

  • The page continues to load after the small 2kb head.min.js file is loaded
  • You can use the latest CSS3 techniques and provide alternate CSS for IE and other old school browsers
  • You can safely use HTML5 tags even with IE
  • You can define JavaScript code on the middle of the page that depend on the scripts on the bottom
  • You’ll have a fast, parallel, non-blocking script loader at your disposal

In addition, you can:

  • Target CSS for specific screen widths, browsers, paths, etc.
  • Style your pages differently depending on the application state, such as whether the user is logged or not

How do you use Head JS?

All script loading is done with head.js()

// the most simple case. load and execute single script without blocking. 
head.js("/path/to/file.js");

// load a script and execute a function after it has been loaded
head.js("/path/to/file.js", function() {
  ...
});

// load files in parallel but execute them in sequence
head.js("file1.js", "file2.js", ... "file10.js");

// execute function after all scripts have been loaded
head.js("file1.js", "file2.js", function() {
  ...
});

// files are loaded in parallel and executed in order they arrive
head.js("file1.js");
head.js("file2.js");
head.js("file3.js");

// the previous can also be written as 
head.js("file1.js").js("file1.js").js("file3.js");

There are even more examples in the usage section at the Head JS homepage that cover:

  • Script organization
  • Labeling scripts
  • CSS3 feature detection
  • Screen size detection
  • Browser detection
  • CSS Routing
  • JavaScript feature detection

[Source on GitHub] [Homepage]


Discussion

Sign in or Join to comment or subscribe

Player art
  0:00 / 0:00