Reconsidering modernizr.js performance defaults

HTML5 won, let's reconsider the defaults for a post-IE8 world

Modernizr is an incredibly useful tool for detecting browser capabilities and dealing with old browsers — it played a key role in the explosion of HTML5 feature adoption and quite rightly shows up all over the web.

However, it's 2013 and web performance is critical for many sites but unfortunately the place where modernizr.js shows up on most sites is in the <head>, violating one of the most important rules of web performance: move scripts to the bottom of the page . This is unsurprising as the installation instructions suggest exactly this:

Drop the script tags in the <head> of your HTML. For best performance, you should have them follow after your stylesheet references. The reason we recommend placing Modernizr in the head is two-fold: the HTML5 Shiv (that enables HTML5 elements in IE) must execute before the <body>, and if you’re using any of the CSS classes that Modernizr adds, you’ll want to prevent a FOUC.
If you don't support IE8 and don't need to worry about FOUC, feel free to include modernizr.js whereever.

That last part is the key: the only thing which Modernizr *needs* to run in the head is the html5shiv, which is only needed for Internet Explorer 8 and earlier — less than 10% of my main project's traffic.

The performance impact will vary depending on your site, how well optimized everything else is and how well connected your users are but it's important to remember that a script in the <head> will block rendering and further script execution until it completes so you're looking at at least one full server round-trip, including the time to download ~5KB of Modernizr code, before the browser can continue. Modern browsers often scan ahead looking for additional resources to start transferring but in some quick webpagetest.org runs I found this was adding a solid 100ms (or ~15%) to the time IE9 took my page to start rendering for a well-connected machine in a major datacenter — for those of us with a global audience, the impact is likely to be much worse unless you have great CDN coverage and high enough traffic to keep the caches warm everywhere.

Since the html5shiv is only needed for IE8, reclaiming that extra speed for everyone else seems like an easy win – and one which avoids making the web slower in order to subsidize people who haven't upgraded yet. Here's what it looks like:

<html>
    <head>
        …
        <!--[if lt IE 9]>
            <script src="html5shiv.min.js"></script>
        <![endif]-->
    </head>
    <body>
        …
        <script src="modernizr.custom.min.js"></script>
    </body>
</html>

As IE8 continues to fade into the sunset, now might be a good time to start moving old shims and polyfills into the slow-lane so we're optimizing for the future, not the past.

comments powered by Disqus