When it comes to front-end performance optimization, the first thing we associate with is file merging, compression, file caching, and enabling server-side gzip compression, which allows pages to load faster and users to use our web applications as quickly as possible to achieve their goals.
Resource preloading is another performance optimization technique that we can use to inform the browser in advance that certain resources may be used in the future.
To quote Patrick Hamann's explanation:
Preloading is a way for the browser to hint at resources that may be used in the future, some of which can be used in the current page and some of which may be used in some future page. As developers, we know our application better than the browser, so we can use this technique for our core resources.
This practice used to be called prebrowsing, but it is not a single technique and can be broken down into several different techniques: DNS-prefetch, subresource, and the standard prefetch, preconnect, and prerender.
DNS pre-resolution DNS-Prefetch
DNS pre-resolution tells the browser that we may get resources from a particular URL in the future, so that when the browser actually uses a resource in that domain, it can complete the DNS resolution as soon as possible. For example, if we might get an image or audio resource from example.com in the future, we could add the following to the tag at the top of the document:
<link rel="dns-prefetch" href="//www.aseoe.com/">
When we request a resource from that URL, we no longer need to wait for the DNS resolution process. This technique is particularly useful for using third-party resources.
As mentioned in Harry Roberts' article:
A simple line of code tells those compatible browsers to perform DNS pre-resolution, which means that DNS resolution is already complete when the browser actually requests a resource in that domain.
This may seem like a very minor performance optimization that doesn't seem all that important, but it's not - Chrome does similar optimizations all the time. Chrome automatically does DNS preresolution (and even page pre-rendering) when a small segment of a URL is entered into the browser's address bar, saving vital time for each request.
Preconnect
Similar to DNS pre-resolution, preconnect will not only complete DNS pre-resolution, but will also perform a TCP handshake and establish the transport layer protocol. It can be used like this:
<link rel="preconnect" href="http://www.aseoe.com/">
There is more detail in Ilya Grigorik's article:
Modern browsers try to predict which connections a website will need in the future and then pre-establish socket connections, thus eliminating costly DNS lookups, TCP handshakes, and TLS round-trip overhead. However, browsers aren't smart enough to accurately predict all pre-link targets for each site. The good news is that in Firefox 39 and Chrome 46 we can use preconnect to tell the browser which preconnects we need to make.
Prefetching
<link rel="prefetch" href="image.png">
Unlike DNS prefetching, prefetching actually requests and downloads the resource and stores it in the cache. But prefetching also depends on a number of conditions, and some prefetches may be ignored by the browser, such as fetching a large font file from a very slow network. Also, Firefox will only prefetch resources when the browser is idle.
As mentioned in Bram Stein's post, this is a significant performance improvement for webfonts. Currently, font files have to wait until the DOM and CSS are built before they start downloading, and using prefetching makes it easy to bypass that bottleneck.
Note: It is a bit difficult to test prefetching of resources, but prefetching of resources is documented in the web panel of both Chrome and Firefox. Also keep in mind that prefetched resources are not restricted by the same-origin policy.
Subresources
This is another prefetching method, which specifies a prefetched resource with the highest priority, before all prefetch items:
<link rel="subresource" href="styles.css">
According to the Chrome documentation:
rel=prefetch provides a low-priority way to preload resources for future pages, while rel=subresource provides a high-priority way to preload resources for the current page.
So, if the resource is required for the current page, or if the resource needs to be available as soon as possible, it is better to use subresource instead of prefetch.
Pre-rendering Prerender
This is a nuclear weapon, because prerender can preload all the resources of the document:
<link rel="prerender" href="http://www.aseoe.com/">
Steve Souders writes in one of his articles:
This is similar to opening a link in a hidden tab page - all the resources are downloaded, the DOM structure is created, the page layout is completed, CSS styles are applied, JavaScript scripts are executed, and so on. Google Search has been using this technology for years in its instant search pages, and Microsoft claims to support this feature in IE11.
Be careful not to abuse this feature, pre-rendering should only be done when you know the user will definitely click on a link, otherwise the browser will unconditionally download all the resources needed for pre-rendering.
More related discussions:
All preloading techniques have a potential risk of mispredicting resources, and the overhead of preloading (grabbing CPU resources, consuming battery, wasting bandwidth, etc.) is high, so care must be taken. While it is difficult to determine which resources the user will access next, highly plausible scenarios do exist:
If a user completes a search with obvious results, the results page will likely be loaded .
If the user goes to a landing page, then the successful landing page is likely to be loaded .
If the user reads a multi-page article or accesses a paginated result set, then the next page is likely to be loaded .
Finally, using the Page Visibility API will prevent the page from being executed before it is actually visible.
Preload
preload is a new specification that, unlike prefetch (which may be ignored), the browser must preload the resource:
<link rel="preload" href="image.png">
Although the specification is not yet compatible with all browsers, the idea behind it is still very interesting.
Summary
Predicting which resources a user will access next is difficult and requires a lot of testing, but the performance improvement this brings is obvious. If we are willing to try these pre-fetching techniques, it will surely improve the user experience significantly.