

There are a few ways to ensure that the browser will already have a page in its cache when users visit them. In this particular case, I wanted improve the load time of the Persona dialog while users are busy looking at the third-party site they want to login into.

Hidden images and iframes


Ignoring the fact that this is now usually blocked because it looks like a web bug (2x2 is the way to go now), the problem with this technique is that the browser now has to pull two images at once, which, for slower connections, means that the load time for the initial page will be longer.

A variant of this technique, with the same problem, is to load the next page in a hidden iframe:

<iframe style="display: none" src="/prefetch.html"></iframe>  

XHR fetch after the page load

A more modern version of the hidden image technique is to use an XHR request to download the resources to the cache once the page has finished loading.

It looks like this:

window.onload = function () {  

The main downside of this solution is that you can only prefetch resources on the same server because of browsers' same-origin restrictions (unless you can use HTTP access controls (CORS)). In the case of Persona though, I wanted third-party sites to trigger the prefetching of resources available from a different host:

HTML5 has defined a prefetch relation type for links and similar tags. All you need to do to use it is to put something like this in your page head:

<link rel="prefetch" href="/img/background.jpg">  
<link rel="prefetch" href="/css/styles.css">  
<link rel="prefetch" href="/js/navigation.js">  


Prefetching will not parse HTML or execute Javascript though (i.e. it's not recursive). So if you want to put a page and all of its resources into the cache ahead of time, you'll need to have link tags for each child resource in the page head.

While this has been implemented in Chrome, it got disabled when they added support for the non-standard prerender relation type. So right now, you may need to use both. Note that either of these relations include DNS resolution, which makes dns-prefetch relations unnecessary.

Dynamic list of resources to prefetch


Ideally, we would give the browser a list of resources to prefetch. While that feature doesn't exist yet, we can approximate it by loading a hidden iframe containing the necessary prefetch links. That way, third-party sites can hardcode the iframe on their pages and you can update the list of resources to prefetch anytime you want.

The great thing about the way Persona works is that we already use an iframe as a commnication channel between the site and the code on So all I had to do in the end was to add prefetch links to that existing iframe. The result of this is that every site using the Observer API gets the benefit of prefetching without having to change anything!


If you want to make sure that your prefetching works:

  1. Clear your browser cache.
  2. Load the page that has prefetch links.
  3. Take a look at the contents of your cache (about:cache in Firefox and chrome://cache/ in Chrome) and look for the resources that should be prefetched.