Chris Adams

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.

Google Analytics Site Speed considered misleading

… maybe one of their mathematicians can explain the difference between mean and median to the marketing folks?

Google Analytics has a very handy site speed feature tracking the time your users' browsers took to load the page. Unfortunately, all of the timing reports make a novice statistical mistake by reporting the average rather than more robust metrics like 90th percentile. Many people have heard that averages are prone to outliers but it's easy to forget the degree to which a reported average can misrepresent something as variable as Internet traffic. Here are two pictures showing why it's not even worth looking at the Site Speed value:

World map of load times for a single AJAX request: note the United States at 5.9 seconds!
Drilling down revealed the US average around .3 seconds for every state except New Jersey and even there the high average was limited to one small town with the shockingly-high average of 47 seconds! Fortunately, the data we actually need is available: the performance tab displays the distribution of timings, allowing us to see that even when considering only traffic from the same town, the vast majority (97%) of requests were loaded in a tenth of a second or less and 99% were loaded in under one second.

Since these values occurred only a single-digit number of times globally and are extremely high – does anyone really wait an hour for a web-page to load? – it's almost certain that they reflect some sort of measurement error in the browser. This is to be expected on the Internet — Flickr famously observed a reported load time which pre-dated that page being added to the site — and it's why you need to use something like a 95th percentile or histogram for any kind of real-world performance reporting so you can measure and act on values which are representative of what most of your users experience rather than wasting time chasing chimeras.

In summary: 3 data points out of 213,000 are enough to skew the average by a factor of 10 or more. When using Google Analytics pretend the summary page doesn't exist and look at the performance distribution.

Google Analytics performance monitoring details

The first rule of benchmarking: make sure you know what you actually measured

Google Analytics has a very handy "Site Speed" report which measures the average load time for your pages as seen by your users. Unfortunately, there are two implementation details which are important to keep in mind:

  1. The reports are heavily based on the average load time, which can skew the results pretty heavily: one multi-minute load time from someone in Haiti on a satellite connection outweighs quite a few users with .8 second load times. There is a bucket report but it's a bit clunky and there's no easy way to get the data out to run your own stats. Even a simple switch to using the median would make this report less ominous at first glance and it'd be a really good use for some sort of distribution graphic.
  2. The more interesting problem is that Google Analytics uses the W3C Navigation Timing API and reports only the value of window.performance.timing.loadEventStart - window.performance.timing.navigationStart. The browser won't fire the load event until all resources on the page have been loaded including external services like Google Analytics. Unfortunately, you will find situations where http://google-analytics.com/ga.js takes a considerable amount of time to respond (yesterday I had 40 second response in a webpagetest.org session) and this will be reflected in your stats even if the page loaded considerably faster from the user's perspective.

    I'm currently experimenting with deferring loading Google Analytics until after the load event using this code. Initial testing appears promising and the elapsed time to load everything else is definitely more accurate:

    Relying on NavigationTiming does mean that you won't receive any information from older versions of Internet Explorer unless they have the Google Toolbar installed, which means some of your worst-performing clients will be invisible. Chrome Frame would be my preferred response…

The Movie Set That Ate Itself

“Seventy years of quotidian misery held with one waistband.”

Five years ago, a relatively unknown (and unhinged) director began one of the wildest experiments in film history. Armed with total creative control, he invaded a Ukrainian city, marshaled a cast of thousands and thousands, and constructed a totalitarian society in which the cameras are always rolling and the actors never go home

#

Source: http://www.gq.com/entertainment/movies-and-tv/201111/movie-set-that-ate-itself-dau-ilya-khrzhanovsky?printable=true&currentPage=all