Editor’s note: This article is part of our Code Optimization series, where we take a look at how to optimize coding for better efficiency in a bid to be better coders.
"Foreseeing" browsers are the future of top speed Internet surfing, bringing us resources we want even before we know we want them. Today’s browsers already make some predictions now and then to speed up fetching and rendering of documents. To take this to the next step, we look to none other than web developers.
Developers have a pretty good idea of how their websites are navigated, and which resources are requested most often and thus, they can predict some future operations browsers should do for sites. All that’s needed now is for developers to find a way to relay these predictions to browsers and put them to good use. This is where some special "HTML links" come in.
A Refresher on HTTP Requests
Before taking a look at these links, it’s time to refresh our memory on how a typical HTTP-requested file-fetching operation happens. Let’s say someone named Joe wants to visit a website.
Here’s what happens next:
- Joe types the website’s humanly recallable address in a browser’s address bar and presses "Enter".
- Once it received that address, the browser asks a DNS server (compliments of ISP) for the IP address of the address given by Joe.
- The DNS server obliges.
- Now that the browser knows the IP address, it sends a message (in TCP dialect) to the website’s server, asking for a connection.
- If the server is alive and well, it sends a reply acknowledging the browser’s request and the browser responds and acknowledges the server’s message. (Note: Yes, this is an extremely watered down version of a TCP handshake between a client and a server.)
- When the handshakes are over, a connection is established between the two.
- Now, browser changes its dialect style to HTTP and asks the server for the website.
- The server, knowing the home page of the website returns just that, which is received by the browser and shown to Joe who’s waiting very patiently in front of the computer.
A typical HTTP request goes through all that (and more) to fetch a document through the Internet. So if any of these process can be jumpstarted when possible, we can reduce the time we have to wait for the delivery of the resources we want.
HTML Link Relationships
W3C specifies 4 HTML link relationships (
rel for relationship) named
prerender. Together they are called (by W3C) the "Resource Hints". Now, we’ll see what they can do and where they can be used.
1. DNS Prefetch
In DNS prefetch, the domain name resolution (aka getting the matching IP address from DNS server) is done ahead of time.
“DNS requests are very small in terms of bandwidth, but latency can be quite high, especially on mobile networks. By speculatively prefetching DNS results, latency can be reduced significantly at certain times, such as when the user clicks the link. In some cases, latency can be reduced by a second. – Mozilla Developer Network“
Let’s say there’s a reference page in a website with lots of reference links to its sister site. When a user visits the reference page, there’s a high probability that the user will navigate to the sister site. So, an early DNS lookup for the sister site can reduce the time it takes to open the site (thereby improving user experience).
This latency reduction via DNS prefetching can be done by adding this code to the reference page.
<link rel="dns-prefetch" href="//mysistersite.org">
When a browser processes this code in the reference page, it’ll add the DNS lookup of the sister site to its task queues, and when it is free from other high-priority tasks in the queue, it will start the DNS resolution of the sister site.
So when a user finally clicks one of the links that takes them to the sister site, the DNS resolution of that site might have already been completed, and the browser can right away start establishing the client-server TCP connection with the sister site server, making that page load faster.
This feature is available in almost all modern browsers except Safari as of March 2016.
Preconnect is a step further from DNS prefetch, it establishes a connection to the server to which there may be a request sent later in the future.
“Preconnect is an important tool in your optimization toolbox… it can eliminate many costly roundtrips from your request path – in some cases reducing the request latency by hundreds and even thousands of milliseconds. – lya Grigorik“
W3C lists an ideal use case for preconnect: redirects. Developers use redirects for a number of reasons.
In this case, a browser’s next request (redirected site) is 100% predictable, and can be preconnected to, to reduce navigation latency.
Imagine there’s an intermediary site page that redirects to "xyzsite", the following HTML link will make the browser preconnect with the xyzsite server, when it gets to that intermediary page.
<link rel="preconnect" href="//xyzsite.com">
prefetch, for a resource, the browser starts implementing the DNS resolution of the resource’s domain name, then performs a TCP connection with the resource’s server, makes the HTTP request, and finally fetches and stores the prefetched resource in the browser cache.
If you are sure of which resources that will be needed later, that’s the resource to prefetch beforehand; therein lies the catch. Prefetching takes guesswork, and if you guess wrongly, you might actually slow down instead of speed up your site.
“This technique has the potential to speed up many interactive sites, but won’t work everywhere. For some sites, it’s just too difficult to guess what the user might do next. For others, the data might get stale if it’s fetched too soon. It’s also important to be careful not to prefetch files too soon, or you can slow down the page the user is already looking at. – Google Developers“
For online books, galleries, or portfolios, if the user is most likely to browse to the next page, prefetching the resources such as images, can speed things up significantly. Here’s the code to do that.
<link rel="prefetch" href="//xyzsite.com/nextimage.jpg">
Prefetch is supported in Chrome, Firefox and Opera.
Only for HTML pages can prerendering be done. A prerendered HTML page is rendered offline, and is painted to the screen when it’s actually needed by the user. Rendering costs a higher computational work and memory resource; plus, in order to render a page, the browser may need extra resources (like images added to the page) which will lead to more consequent requests by browser.
prerender has to be used with caution, and not overused. Adding the following code will prerender the "About" page beforehand.
<link rel="prerender" href="//example.com/about.html">
prerender hint can be used by the application to indicate the next likely HTML navigation target: the user agent will fetch and process the specified resource as an HTML response. To fetch other content-types with appropriate request headers, or if HTML preprocessing is not desired, the application can use the
prefetch hint. – W3C“
Prerender is already available in Chrome, IE and Opera as of March 2016.
A few Things to Note
(1) None of the abovementioned resource hints guarantee the execution and completion of the different stages of request it’s made for because when the browser is already busy processing the requests needed for the operations of the current page the user is in, performing these optimizations can hinder user’s current tasks.
So, everything is queued and executed when the browser feels free enough to do so.
(2) W3C specifies a HTML link attribute called hint probability,
pr (with value 0 to 1) for these resource hints, which can be used to provide the probability of requests that will be made in the future. I haven’t seen this attribute being implemented by any browser yet though. As an example, the following code states that there’s an 80% chance xyzsite will be requested in the future and 30% for the about page.
<link rel="preconnect" href="//xyzsite.com" pr="0.8"> <link rel="prerender" href="//example.com/about.html" pr="0.3">
We can also add the optional crossorigin attribute to the resource hints to inform the browser of the linked request’s CORS credential.