<link>informs the browser that your page intends to establish a connection to another domain, and that you’d like the process to start as soon as possible. Resources will load more quickly because the setup process has already been completed by the time the browser requests them.
The graphic in the post does a good job of making this an obviously good choice for performance:
Robin did a good job of rounding up information on all this type of stuff a few years back. Looks like the best practice right now is using these two:
<link rel="preconnect" href="http://example.com"> <link rel="dns-prefetch" href="http://example.com">
For all domains that aren’t the main domain you’re loading the document from.
A quick look at CSS-Tricks resources right now, I get:
secure.gravatar.com static.codepen.io res.cloudinary.com ad.doubleclick.com s3.buysellads.com srv.buysellads.com www.google-analytics.com
That’d be 14 extra
<link> tags in the first few packets of data on every request on this site. It sounds like a perf win, but I’d want to test that before no-brainer chucking it in there.
Andy Davies did some recent experimentation:
So what difference can preconnect make?
I used the HTTP Archive to find a couple of sites that use Cloudinary for their images, and tested them unchanged, and then with the preconnect script injected. Each test consisted of nine runs, using Chrome emulating a mobile device, and the Cable network profile.
There’s a noticeable visual improvement in the first site, with the main background image loading over half a second sooner (top) than on the unchanged site (bottom).
This stuff makes me think of instant.page (which just went v2), which is a fancy little script that preloads things based on interactions. It’s now a browser extension (FasterChrome) that I’ve been trying out. I can’t say I notice a huge difference, but I’m almost always on fast internet connections.
How does this play with caching? If I’m a repeat visitor to a page and all the CDN images are cached, the browser doesn’t need to connect to that domain at all. Doesn’t preconnect add unnecessary overhead in that case?
Correct, the first, non-cached visit would benefit from the preconnect, but repeat requests to the same resources could already be cached and would then be served from the cache, making the preconnect unnecessary.
However, you’re still better off with the preconnect because:
(1) You still benefit from the preconnect for that first, non-cached resource request.
(2) Googlebot does not cache resources and hence every resource request is a first, so google’s measured pagespeed will benefit.
(3) Preconnect is not render blocking, occurs asynchronously, does not affect the DOM, and therefore does not affect page speed, time-to-interactive, time-to-first-paint, etc. It’s something that happens entirely independently and in parallel, so pagespeed does not suffer.
(4) Yes, each preconnect will use a miniscule amount of resources on the browser, but only if you’re calling for a very large number of preconnects will that bog down the browser.
(5) If a user visits a first page, the preconnect is peformed and connection to the resource, say CDN, is established. If the user then clicks on a link to go to another page (within the keep-alive time) that also pulls from the CDN, the browser sees the preconnect request on that second page, but also sees that it already has that connection open due to the TCP keep-alive feature of http connections. It therefore obviously won’t try to connect to an already open connection.
I think the dns-prefetch should be redundant, though; preconnect forces your browser to resolve the DNS address anyway.
If the browser supports preconnect, then dns-prefetch is unnecessary since setting up a connection to the host with preconnect will perform a dns lookup anyway. However, some older browsers don’t support preconnect, so the dns-prefetch line is a fallback for those browsers. That way, the browser can at least perform the dns lookup in advance of the resource being requested.
Interesting. How important is the subdomain in those situations?
This opens the entire connection (DNS/TLS/…) to Google Fonts. Cloud be useful because fonts are often used by all pages on your site.
<link rel="preconnect" href="https://fonts.gstatic.com">
But what about the Google API’s uri? Often used by Google Maps or other services, those are not always loaded on all pages so a dns-fetch would be a better fit I guess?
<link rel="dns-fetch" href="https://googleapis.com">
Could this above work perfectly fine or should we really do this:
<link rel="dns-fetch" href="https://maps.googleapis.com">
<link rel="dns-fetch" href="https://ajax.googleapis.com">
<link rel="dns-fetch" href="https://service.googleapis.com">
I think you need the subdomain explicitly in there. Anyone know for sure?
Subdomain/host is necessary since an actual http/TLS connection is being established with the targeted webserver, and maps.googleapis.com is surely a different webserver than ajax.googleapis.com. Not including the subdomain would therefore cause you to establish a connection to the incorrect server, making the preconnect useless.
Regarding google fonts, there’s virtually nothing to gain by a preconnecting to the stylesheet host fonts.googleapis.com to get the stylesheet, since that’s going to get pulled anyway very early on in the html parsing. However, that stylesheet will subsequently request the actual font files from fonts.gstatic.com, so it does help performance to preconnect to fonts.gstatic.com in anticipation.
Using dns-prefetch only makes sense as a fallback to browsers that don’t support preconnect. If you’re targeting only browsers that do support preconnect, then dns-prefetch has no value.
what is the mentioned link will be the current website(I mean an internal absolute link), not an external link?
I think the hard part of this is convincing the deciding powers it’s worth it. Like you said in the last sentence, I’m almost always on fast internet connections.
Thanks for this article. I see that on css-tricks.com you have opted to not use preconnect or dns-prefetch for google-analytics.com. What’s the reasoning behind that. I’m currently considering using these resource hints specifically for Google Analytics and Facebook.
preconnectshould be used for the resources that are going to be loaded on further navigation on website. So IMO, as far as Google Analytics should be available on every page, it is loaded on first page load and there is no need to preload it.