Friday, 4 June 2010

The Javascript downloading dilemma…

I was struggling with a bit of a optimisation dilemma regarding the downloading of javascript last week (until Steve Souders and Chapter 8 of High Performance Websites showed me the answers) so I thought it might be worth sharing my thought process here to see what you think? Skip to the bottom if you want to hear the answer!

*******

As I interpret the performance rules the "ideal" solution for Javascript would be:

  1. only download the javascript you need for that page (reduce page weight)
  2. ideally download it in one file (reduce HTTP requests)
  3. load/execute it last on the page (avoid blocking)
  4. and ideally use the OnLoad event to defer it to "behind the scenes"

Regarding (1) &  (2) this led me to think "well, if you broke each JS function into a separate file you could (at build time) create a targeted JS file for each page (or more likely page template in your CMS) that only contains the functions required by that page".

But then caching becomes a factor - a "unique" javascript file per page/template would require that the "unique" javascript file to be downloaded the first time you visit that page, and the "unique" file for the next page, and the next page and so on as you navigate on a user journey through the site.

A "shared" javascript library across the site however ("lets stick everything on one big file" like so many of our clients do...) has the benefit of being downloaded on the first page you hit, and then re-used from cache for all the other pages in a user journey.

But then you are back to breaking rule (1) and downloading a lot of stuff you don't need, and in particular you might be slowing down the user experience on that crucial landing page on your site.

So maybe you are better to do some sort of "on-demand" loading and retrieve the javascript functions in a lot of little files that can be used by all the pages in the site... but that breaks rule (2) (potentially in a big way!).

So is there any way to devise some heuristic "rules of thumb" on how to create an optimal solution of the "minimum set of javascript, in the minimum downloads, but maximally cacheable and re-usable across pages in a user journey"?

As I see it the "ideal" might be something like this:

  1. each page has a unique minimal set of javascript that is used on the first visit to a page by a "new visitor" (so this optimises that first visit experience)
  2. the OnLoad event downloads "in the background" a "shared" library for the site containing a larger set of common functions
  3. on "page 2" of the user journey the page determines "does the user have the shared library" (e.g. server-side by looking at a cookie, not quite sure how this is would be done client-side) and then either uses the shared library OR downloads its own "unique" library if not.

*******

And the answer (as per Chapter 8) is… pretty much like I outlined above (serve different javascript based on cookies), but I had left out one important factor – inline javascript adds another dimension to the dilemma “when to inline and when to use external javascript files”.

Steve Souders points out that “inline is faster” (by about 30-50% according to page 55) but “external is re-usable”.

So there is a trade-off – speed from inline versus speed from cached external javascript re-use.

The key then is calculating your javascript re-use ratio… which has 2 factors I think:

  1. what is your overall browser cache hit ratio (which you can calculate using the Yahoo!" technique discussed here - http://www.yuiblog.com/blog/2007/01/04/performance-research-part-2/)
  2. how much of the javascript you send to the user is actually shared across the pages…

Currently I have no answer to (2) but I am open to ideas!

- Steve

0 comments:

Post a Comment