Scripts At The Bottom Is Not Enough

You may remember one of the original webperf rules was to put scripts at the bottom.

Over the last few years browsers have been adjusting, now it is common for JavaScript to have higher loading priority via a pre-loader. This can result in scripts at the bottom effectively loading the same as scripts at the top.

Patrick Meenan on how it is supposed to work ( emphasis mine ):

– The preload scanner scans the whole document as it comes in and issues fetch requests.
– The main parser sends a signal when it reaches the start of the body and sends fetch requests for any resources it discoveres that are not already queued.
– The layout engine increases the priority of in-viewport visibile images when it does layout.
The resource loader treats all script and css as critical, regardless of where it is discovered (in the head or at the end of the body). see
– Resource loader loads in 2 phases. The first (critical phase) delays non-critical resources except for 1 image at a time. Once the main parser reaches the body tag it removes the constraint and fetches everything.

At this point you’ll likely need to use async/defer to really push JavaScript loading out of the critical category. Of course that isn’t a slam dunk either. Paul Irish notes this limitation with IE:

TL;DR: don’t use defer for external scripts that can depend on eachother if you need IE <= 9 support

Even after 20 years of development there are days where browser environments still feel like the wild west.

IDs in Window

When you assign a DOM element an ID, that ID becomes part of the window object. No joke, in the spec even ( emphasis mine ):

7.2.4 Named access on the Window object

The Window interface supports named properties. The supported property names at any moment consist of the following, in tree order, ignoring later duplicates:

the value of the id content attribute of any HTML element in the active document with a non-empty id content attribute.

On the sidebar section has an ID of “sidebar”, which is easily accessed in the Chrome Console:


I’d recommend never doing this in real code ( great for quick debugging in the JavaScript console though ). Instead stick with document.getElementById( 'thingid' );, which is significantly faster.

Progressive Enhancement, Where Art Thou?

Drew McLellan wonders Why is Progressive Enhancement so unpopular?:

Does that mean we shouldn’t use JavaScript? Of course not. Scripting in the browser is an important part of the experience of using the web in 2014. It’s my opinion that you shouldn’t depend on JavaScript running for your site to work. Build with HTML, add styling with CSS, add behaviour with JavaScript. If the JavaScript fails, the HTML should still work.

Simon St. Laurent touched on this as well in Web Application Development is Different (and Better):

Let’s extend the Web and help it do more – but let’s do that by valuing the many strengths it already brings.

Intentional or not the last few years have brought us a strong push to ignore the idea of progressive enhancement. In many cases that has been to our detriment.

Page Visibility

The W3C recommendation on Page Visibility was updated this week. Being able to detect if a tab currently has focus is an opportunity to adjust features and performance accordingly.

The HTML5 Rocks tutorial on Page visibility has example that automatically pauses a video when the tab is out of focus. The Mozilla Developer Network also uses the video pause example for Page Visibility. Must be the “Hello World” of Page Visibility examples.

Another example would be to turn down the update frequency when a tab is out of focus. No point in updating a page every second, even with a websocket, if the tab is in the background. The Page Visibility API makes it easy to dial the frequency down to something more modest, like once a minute, then turn it back up again when the tab gets focus.

Browser support for the Page Visibility API is pretty good in current versions. The two exceptions are Opera Mini and the Android Browser.

To deal with cross browser differences check out Visibility.js.