Last year, we demonstrated what we meant by “lightning fast”, showing Pages' first-class performance in all parts of the world, and today, we’re thrilled to announce an integration that takes this commitment to speed even further – introducing Pages support for Early Hints! Early Hints allow you to unblock the loading of page critical resources, ahead of any slow-to-deliver HTML pages. Early Hints can be used to improve the loading experience for your visitors by significantly reducing key performance metrics such as the largest contentful paint (LCP).
What is Early Hints?
Early Hints is a new feature of the Internet which is supported in Chrome since version 103, and that Cloudflare made generally available for websites using our network. Early Hints supersedes Server Push as a mechanism to "hint" to a browser about critical resources on your page (e.g. fonts, CSS, and above-the-fold images). The browser can immediately start loading these resources before waiting for a full HTML response. This uses time that was otherwise previously wasted! Before Early Hints, no work could be started until the browser received the first byte of the response. Now, the browser can fill this time usefully when it was previously sat waiting. Early Hints can bring significant improvements to the performance of your website, particularly for metrics such as LCP.
How Early Hints works
Cloudflare caches any preload
and preconnect
type Link
headers sent from your 200 OK response, and sends them early for any subsequent requests as a 103 Early Hints response.
In practical terms, an HTTP conversation now looks like this:
Request
GET /
Host: example.com
Early Hints Response
103 Early Hints
Link: </styles.css>; rel=preload; as=style
Response
200 OK
Content-Type: text/html; charset=utf-8
Link: </styles.css>; rel=preload; as=style
<html>
<!-- ... -->
</html>
Early Hints on Cloudflare Pages
Websites hosted on Cloudflare Pages can particularly benefit from Early Hints. If you're using Pages Functions to generate dynamic server-side rendered (SSR) pages, there's a good chance that Early Hints will make a significant improvement on your website.
Performance Testing
We created a simple demonstration e-commerce website in order to evaluate the performance of Early Hints.
This landing page has the price of each item, as well as a remaining stock counter. The page itself is just hand-crafted HTML and CSS, but these pricing and inventory values are being templated in live for every request with Pages Functions. To simulate loading from an external data-source (possibly backed by KV, Durable Objects, D1, or even an external API like Shopify) we've added a fixed delay before this data resolves. We include preload
links in our response to some critical resources:
an external CSS stylesheet,
the image of the t-shirt,
the image of the cap,
and the image of the keycap.
The very first request makes a waterfall like you might expect. The first request is held blocked for a considerable amount of time while we resolve this pricing and inventory data. Once loaded, the browser parses the HTML, pulls out the external resources, and makes subsequent requests for their contents. The CSS and images extend the loading time considerably given their large dimensions and high quality. The largest contentful paint (LCP) occurs when the t-shirt image loads, and the document finishes once all requests are fulfilled.
Subsequent requests are where things get interesting! These preload
links are cached on Cloudflare's global network, and are sent ahead of the document in a 103 Early Hints response. Now, the waterfall looks much different. The initial request goes out the same, but now, requests for the CSS and images slide much further left since they can be started as soon as the 103 response is delivered. The browser starts fetching those resources while waiting for the original request to finish server-side rendering. The LCP again occurs once the t-shirt image has loaded, but this time, it's brought forward by 530ms because it started loading 752ms faster, and the document is fully loaded 562ms faster, again because the external resources could all start loading faster.
The final four requests (highlighted in yellow) come back as 304 Not Modified responses using a If-None-Match
header. By default, Cloudflare Pages requires the browser to confirm that all assets are fresh, and so, on the off chance that they were updated between the Early Hints response and when they come to being used, the browser is checking if they have changed. Since they haven't, there's no contentful body to download, and the response completes quickly. This can be avoided by setting a custom Cache-Control
header on these assets using a _headers
file. For example, you could cache these images for one minute with a rule like:
# _headers
/*.png
Cache-Control: max-age=60
We could take this performance audit further by exploring other features that Cloudflare offers, such as automatic CSS minification, Cloudflare Images, and Image Resizing.
We already serve Cloudflare Pages from one of the fastest networks in the world — Early Hints simply allows developers to take advantage of our global network even further.
Using Early Hints and Cloudflare Pages
The Early Hints feature on Cloudflare is currently restricted to caching Link
headers in a webpage's response. Typically, this would mean that Cloudflare Pages users would either need to use the _headers
file, or Pages Functions to apply these headers. However, for your convenience, we've also added support to transform any <link>
HTML elements you include in your body into Link
headers. This allows you to directly control the Early Hints you send, straight from the same document where you reference these resources – no need to come out of HTML to take advantage of Early Hints.
For example, for the following HTML document, will generate an Early Hints response:
HTML Document
<!DOCTYPE html>
<html>
<head>
<link rel="preload" as="style" href="/styles.css" />
</head>
<body>
<!-- ... -->
</body>
</html>
Early Hints Response
103 Early Hints
Link: </styles.css>; rel=preload; as=style
As previously mentioned, Link
headers can also be set with a _headers
file if you prefer:
# _headers
/
Link: </styles.css>; rel=preload; as=style
Early Hints (and the automatic HTML <link>
parsing) has already been enabled automatically for all pages.dev
domains. If you have any custom domains configured on your Pages project, make sure to enable Early Hints on that domain in the Cloudflare dashboard under the "Speed" tab. More information can be found in our documentation.
Additionally, in the future, we hope to support the Smart Early Hints features. Smart Early Hints will enable Cloudflare to automatically generate Early Hints, even when no Link
header or <link>
elements exist, by analyzing website traffic and inferring which resources are important for a given page. We'll be sharing more about Smart Early Hints soon.
In the meantime, try out Early Hints on Pages today! Let us know how much of a loading improvement you see in our Discord server.