Table of contents of the article:
Want to know a secret about Internet performance? Browsers spend an inordinate amount of time twiddling their thumbs waiting to know what to do. This wait affects page load performance. Today we are happy to discuss what Early Hints are, which greatly improves browser page load performance and reduces wait time.
What are Early Hints?
If we translate the term "Early Hints" literally, we will get "First Suggestions" in Italian. This term is certainly much more immediate and eloquent to better understand the functionality proposed as early as 2017 which sees light towards the end of June 2022.
Websites have gotten more sophisticated over time. Therefore, it is not unusual for a server to perform non-trivial work (for example, accessing databases or CDNs accessing the origin server) to produce the HTML for the requested page. Unfortunately, this "server thinking time", technically called "Thinking Time", results in additional latency before the browser can begin rendering the page. In effect, the connection actually remains idle for as long as it takes for the server to prepare the response.
Early Hints is an HTTP status code ( 103 Early Hints
) used to send a preliminary HTTP response before a final response. This allows a server to send suggestions to the browser about critical sub-resources (for example, style sheet for the page, critical JavaScript) or sources that will likely be used by the page, while the server is busy generating the primary resource. The browser can use these tips to heat up connections and request secondary resources while waiting for the primary resource. In other words, Early Hints helps the browser take advantage of that "server think time" by doing some work ahead of time, thus speeding up the page load.
In some cases, the performance improvement for the largest Contentful Paint it can go from several hundred milliseconds, as observed by Shopify e by Cloudflare , and up to one second faster, as shown in this before / after comparison:
The page cannot be rendered (and the shopper can't get the coffee fix and the coffee shop can't get paid!) Until the key assets are loaded. Information about the sub-resources needed by the browser to load the page is not available until the server has waited and returned the initial response (the first document in the table above).
In the previous example, the page loading could have been speeded up if the browser had known, before receiving the full response, that the stylesheet and the next four scripts would be needed to render the page.
The attempt to parallelize this dependence is Early Hints' goal: to use productively that "server wait time”To allow the browser to perform critical steps for rendering the page before the full server response arrives. The green "thinking" bar overlaps the blue "download content" bar, allowing both the browser and the server to prepare the page at the same time. No more waiting. That's what Early Hints is all about!
“Entrepreneurs know that first impressions matter. Shopify data shows that on average, when a store improves first page speed in the buyer's journey by 10%, there is a 7% increase in conversions. We see great promise in Early Hints as another tool to help improve performance and experience for all merchants and customers. "
— Colin Bendell , Shopify's Director of Performance Engineering
Early Hints implementation
Early Hints is available starting with version 103 of Chrome, in response to browsing requests or user interactions that change the URL in the status bar, with support for both preconnection and preload suggestions.
Before we delve into the subject, keep in mind that initial suggestions aren't helpful if your server can immediately send a 200 (or other final responses). Instead, consider using the normal response link rel=preload
o link rel=preconnect
on the main answer ( Link rel HTTP header ) or in the main answer ( <link>
elements), in such situations. For cases where your server needs some time to generate the main response, read on!
In a very direct way, beyond many technical virtuosity, if you are using an efficient static cache with a Time To First bytes very low and fast (less than 200ms), the Early Hints probably won't offer any tangible advantage if not perhaps in the order of a few milliseconds.
The first step in taking advantage of Early Hints is to identify your top landing pages - the pages your users typically start from when they visit your website. This could be the home page or popular product listing pages if you have a lot of users from other websites. The reason these entry points matter more than other pages is because the usefulness of Early Hints decreases as the the user browses your website (that is, the browser is more likely to have all the sub-resources it needs in the next second or third navigation). It's always a good idea to make a great first impression too!
Now that you have this priority list of landing pages, the next step is to identify which sources or sub-resources would be good candidates for your suggestions. preconnection o preload , as a first approximation. Typically, these are sources and secondary resources that contribute the most to key user metrics such as Largest Contentful Paint o First contentful paint . More concretely, look for secondary resources that block rendering such as synchronous JavaScript, style sheets, or even web fonts. Likewise, look for sources that host sub-resources that contribute a lot to key user metrics. Note: if your primary assets are already using <link rel=preconnect>
o<link rel=preload>
, you can consider these sources or assets as candidates for Early Hints. You see this article for more details.
While this is a decent starting point, it's not necessarily enough. The second step is to minimize the risk of using Early Hints on resources or sources that may be out of date or no longer in use by the primary resource. For example, resources that are updated frequently and with version (for example example.com/css/main.fa231e9c.css
) may not be the best choice. Note that this concern is not specific to Early Hints, it applies to any link rel=preload
o rel=preconnect
wherever they could be present. This is the kind of detail that is best dealt with automation or modeling (for example, a manual process is more likely to lead to mismatched hash or version URLs between link rel=preload
and the actual HTML tag that the resource uses).
As an example, consider the following flow:
GET /main.html
Host: example.com
User-Agent: [....] Chrome/103.0.0.0 [...]
The server expects that main.abcd100.css
will be needed and suggests preloading it via Early Hints:
103 Early Hints
Link: </main.abcd100.css>; rel=preload; as=style
[...]
A few moments later, the web page is served, including the linked CSS. Unfortunately, this CSS resource is updated frequently and the main resource is already five versions ahead ( abcd105
) of the expected CSS resource ( abcd100)
.
200 OK
[...]
<HTML>
<head>
<title>Example</title>
<link rel="stylesheet" href="/main.abcd105.css">
In general, aim for sources and origins that are fairly stable and largely independent of the outcome for the primary resource. If necessary, you might consider splitting your key assets into two: a stable part designed to be used with Early Hints, and a more dynamic part left to retrieve after the primary resource is received by the browser:
<HTML>
<head>
<title>Example</title>
<link rel="stylesheet" href="/main.css">
<link rel="stylesheet" href="/experimental.3eab3290.css">
Finally, on the server side, look for top resource requests sent by browsers known to support Early Hints and respond immediately with 103 Early Hints. In answer 103, include relevant preconnect and preload suggestions. Once the primary resource is ready, continue with the usual response (for example, 200 OK if successful). For backward compatibility, it is a good idea to also include Link
HTTP headers in the final response, perhaps augmenting even with critical resources that became apparent as part of generating the main resource (for example, the dynamic part of a key resource if you followed the "split in two" tip). Here's what it would look like:
GET /main.html
Host: example.com
User-Agent: [....] Chrome/103.0.0.0 [...]
103 Early Hints
Link: <https://fonts.google.com>; rel=preconnect
Link: </main.css>; rel=preload; as=style
Link: </common.js>; rel=preload; as=script
A few moments later:
200 OK
Content-Length: 7531
Content-Type: text/html; charset=UTF-8
Content-encoding: br
Link: <https://fonts.google.com>; rel=preconnect
Link: </main.css>; rel=preload; as=style
Link: </common.js>; rel=preload; as=script
Link: </experimental.3eab3290.css>; rel=preload; as=style
<HTML>
<head>
<title>Example</title>
<link rel="stylesheet" href="/main.css">
<link rel="stylesheet" href="/experimental.3eab3290.css">
<script src="/common.js"></script>
<link rel="preconnect" href="https://fonts.googleapis.com">
Early Hints support for various HTTP web servers
Here is a brief summary of the level of support for Early Hints among the most popular HTTP OSS server software:
- Apache: supported via mod_http2.
- H2O: supported .
- nginx: experimental module .
- node: not yet supported by the core. Available as draft plug-in for Fastify .
It must necessarily be considered that at the base of CloudFlare there is the Web Server NGINX (pronounced Engine X) and therefore also considering the business dynamics and the propensity for Open Source, that this Patch (as happened for the QUIC patch) can also be released for NGINX. If not, we are quite convinced that within 6 or 12 months, this feature will be released by the development team of the NGINX webserver.
Enable Early Hints, the easy way
If you're using one of the following CDNs or platforms, you may not need to manually implement the initial suggestions. Refer to your solution provider's online documentation to find out if it supports initial suggestions, or refer to the non-exhaustive list here:
Early Hints on CloudFlare
Cloudflare, as the perimeter network that sits between client and server, is well positioned to provide these tips to clients on behalf of servers. This is true for a few reasons:
- 103 is an experimental status code that origins may not be able to emit on their own, mostly for legacy reasons. Much of the mechanisms that power the Web presuppose wrongly HTTP requests always match 1: 1 with HTTP responses. This erroneous premise is built into most HTTP server software, making it difficult for origin servers to issue Early Hints 103 responses before a "final" 200 OK response.
Cloudflare edge servers that handle this complexity on behalf of our customers neatly evade these technical challenges and spin the adoption flywheel on this exciting new technology faster (more on that later). - Cloudflare's edge is very close to end users . This means we can provide suggestions very quickly, filling even the smallest thought blocks of the server with useful information that the client can use to start loading resources right away.
- Cloudflare already sees the flow of inquiries and responses from our customers. We use this data to automatically generate recommendations, without a customer having to make changes to the source.
Advanced model
If you've fully applied the initial tips to your key landing pages and find yourself looking for more opportunities, you may be interested in the following advanced outline.
For visitors who are at theirs umpteenth page request as part of a typical user journey, you may want to tailor the Early Hints response to content that is lower and deeper on the page, in other words using Early Hints on lower priority resources. This may seem counterintuitive as we have recommended focusing on high priority resources or secondary sources, which block rendering. However, when a visitor has been browsing for a while, it is very likely that their browser already has all the critical resources. From there on, it might make sense to shift your focus to lower priority resources. For example, this could mean using Early Hints to load product images or additional JS / CSS only needed for less common user interactions.
Current Early Hints limits
Here are the limitations of Early Hints implemented in Chrome 103 and future releases until further notice:
- Available only for navigation requests (which is the primary resource for the top-level document).
- It only supports preconnect and preload (that is, preload is not supported).
- Early Hint followed by a multi-origin redirect on the final response will result in Chrome deleting the resources and connections obtained through Early Hints.
What's the next step?
Depending on the interest of the community, we can augment our Early Hints implementation with the following capabilities:
- Initial suggestions sent on sub-resource requests.
- First suggestions posted on iframe core resource requests.
- Support for prefetching in the first tips.
Relation with HTTP2 Push or H2 / Push
If you are familiar with the deprecated HTTP2 / Push function , you may be wondering how Early Hints differs. While Early Hints requires a round trip for the browser to start fetching critical sub-resources, with HTTP2 / Push the server could start sending sub-resources along with the response. While this sounds surprisingly, it came with a key structural drawback: with HTTP2 / Push it was extremely difficult to avoid sending sub-resources that the browser already had. This “over-pushing” effect resulted in less efficient use of network bandwidth, which significantly hindered the performance gains. Overall, Chrome's data showed that HTTP2 / Push was actually a distinct negative for web performance.
Conversely, Early Hints works best in practice because it combines the ability to send a preliminary response with suggestions that leave the browser to retrieve or connect to what it actually needs. While Early Hints doesn't cover all the use cases HTTP2 / Push could theoretically address, we believe Early Hints is a more practical solution for speeding up browsing.
Conclusion on Early Hints and web performance
What we always repeat and we will never tire of repeating is that web performances are a process and not a product. Thinking of enabling Early Hints, implementing CloudFlare and then not having a static cache like Varnish, not having an adequate tuning of the PHP-FPM pools, having slow queries on the Database, an underpowered hardware architecture, the lack of brotli compression, the lack of of TCP BBR with 0-RTT, will lead to nothing but the conviction of having solved one of the many dozen problems that must be previously solved before inserting Early Hints.
It is not enough to buy and wear Usain Bolt's running shoes to break the world record, just as it is not enough to enable Early Hints on the Web server to have a fast site.
We remind you of this article about the various steps to keep an eye on to have a fast site.