Harry Roberts, consultant front-end architect at CSS Wizardry, discussed how web pages can be made faster with resource hints in a recent talk at WebExpo 2019, held in Prague.
Roberts started with quoting the W3C Resource Hints specifications which defines resource hints as follows:
[Resource hints] enable the developer, and the server generating or delivering the resources, to assist the user agent in the decision process of which origins it should connect to, and which resources it should fetch and preprocess to improve page performance.
Roberts then gave his own practical definition, in which resource hints are single lines of HTML which can result in faster websites. In the rest of the talk, Roberts focused on 5 types of resource hints.
The dns-prefetch
hint is intended to resolve the IP address for a given domain ahead of time. It may be useful when the domain that will be accessed is known, but not necessarily the full URL. The corresponding HTML line to include in the <head>
tag is as follows:
<link rel="dns-prefetch" href="https://www.youtube.com" />
While resolving common names can take on average between 80 and 120ms, with some enterprise-grade DNS servers shortening that to 60ms, resolving uncommon names may take up to 200-300ms. Worse cases (like brand new names, overworked name resolvers) may have a total resolution time between 1 and 10s.
The preconnect
hint involves doing not only the DNS lookup, but also the TLS negotiation, and the TCP handshake. The syntax is as follows:
<link rel="preconnect" href="https://fonts.googleapis.com" />
By allowing the browser to setup early connections before an HTTP request is actually sent to the server, it is possible to eliminate roundtrip latency. This is particularly useful for resources on the critical path and can save hundreds of milliseconds.
Roberts however recommends to warm up only the frequent and likely origins. Opening many connections can have a CPU and battery cost, and Chrome can only run simultaneously 6 DNS resolutions.
The third resource hint discussed is prefetch
, which identifies a file needed for subsequent navigations. Using prefetch
involves predicting where the user might go after the page that is currently being loaded. When a prefetch takes place, the browser looks up the DNS, establishes the connection as with preconnect
, but then also requests and downloads the referenced files. The fetched files are however not parsed nor executed.
The performance gains will depend on the accuracy of the prediction of subsequent navigations. Wrong predictions may lead to wasted time and resources in downloading something that is not going to be used.
The syntax is as follows:
<link rel="prefetch" href="https://code.jquery.com/jquery-3.4.0.js" />
The fourth resource hint, preload
involves a mandatory fetch for a file needed for the current navigation. preload
is stricto sensu not a hint, as it is mandatory, and as such has its own specifications. An example of declaration in a HTML header, and which involves a few important attributes, is as follows:
<link rel="preload" href="/assets/webfont,woff2" as="font" type="font/woff2" crossorigin />
The preload
resource hint gives a way to surface late discovered resources, i.e. resources which cannot be collected from the HTML source. Roberts gives the example of a Single Page Application (SPA) which downloads some HTML, which leads to download and run some JavaScript, which in turn computes a virtual representation of the DOM (VDOM), which then injects some CSS, the latter referencing a font and a background image. Resources are fetched as they are discovered, which leads to sequentially fetching resources. Using preload
may lead to fetching resources in parallel by telling the browser in advance what resources will be discovered. In the SPA case, the CSS, fonts and background images may be downloaded before the VDOM computation occurs.
Roberts however urges developers to exercise caution. The as
attribute, which indicates the type of the downloaded file within a closed list of 12 types, lets the browser assign priority and optimize the delivery of certain resources. Developers should use as
correctly and not seek to trick the browser into downloading some resources with a higher priority than intended. The penalty in such cases would be that resources may be downloaded twice, destroying the performance gain that was being sought for.
Furthermore, it may happen that the Chrome browser over-prioritizes preloads, and dispatches preloads before other critical resources. Roberts observed in its latest projects that often, Chrome returns less-critical resources sooner, and gave an example where using preload
led to a 0.4ms delay to start rendering the page. As a matter of fact, Roberts mentioned having had to remove the preload
optimization for some websites.
The last resource hint is prerender
. The syntax is as follows:
<link rel="prerender" href="/login/" />
Roberts described important usage and security issues which led to reconsider the original prerender
semantics. prerender
was originally meant to prerender pages in the background. Due to the potential for misuse of the feature (Roberts detailed issues with bandwidth, traffic measurement, ad-tracking, and security), the prerender
API remained, with updated semantics. prerender
thus no longer implies page preredering and instead leads to resource prefetching for the 'prerendered' page. The feature is now called NoState Prefetch.
Roberts concluded with encouraging developers to experiment with resource hints:
[Resource hints] are quick, cheap and effective. [They] are generally very safe to implement -- the browser will help you. [They] can be applied to a multitude of use cases [...]. Go for it!
Webexpo is a conference for developers, UX professionals, designers, and marketers to meet up and share their experiences. WebExpo 2019 took place in September 20-22, 2019 in Prague, Czechia.