Early Hint || The 103 Status Code and How to Implement It.15 min read

Early Hint || The 103 Status Code and How to Implement It.<span class="wtr-time-wrap after-title"><span class="wtr-time-number">15</span> min read</span>

What is an Early Hint?

Early Hint is an HTTP response message with a status code 103, used with the Link Header to tell a user’s browser to perform some tasks while waiting for the main response with the status code 200.

On the web, improvements are always made to almost everything as developers develop better ways to perform different tasks and improve their performance. Early Hint is one of these many improvements.

Early Hint was developed to improve the rending time of a webpage by putting to using the ‘server think-time’.

What is Server Think-Time?

The server think-time is the term used to refer to the period between when a browser sends an HTTP request to a server and when the server sends an HTTP response (200 OK) to the browser. The server is said to be ‘thinking‘ during this period, and this is what the Early Hint takes advantage of to improve performance.

How The Communication Between A Browser And A Server Works.

I would like to take you and this current page you are reading now as an example to explain how your browser communicated with our server in other to render this page for you.

The very moment you did click on the link to this page, your browser developed an HTTP request for this page, and it sent it to our server, but in this case, it did send it to the closest CDN node because we make use of a CDN.

This HTTP request contains details of what the browser wants as a response to its request, and in this case, your browser needed the payload for this page.

When our server did receive the request from your browser, it began to process the request and try to locate the exact page your browser requested for. This took a few hundred milliseconds, and this is referred to as the Server Think-Time.

When our server was done with the process, it sent an HTTP response to your browser, and that was when your browser was able to begin the process of rendering this page for you.

While rendering this page, your browser found some resources (like fonts, images, Javascript, etc.) it needed to render. As soon as it came across them, either in the HTTP Response Header, the <head> element, or the <body> element, it requested those resources and had to wait for them before it could continue rendering the page.

Communication between a server and a browser without an early hint.
Source: Chrome.

This is how everything would work without an Early Hint. Now let’s see what happens when there is an early hint.

How does the Early Hint Work?

When a browser requests a page with an early hint in its server, here is what happens: Immediately after the server receives the request and identifies the page requested, it sends a 103 status code HTTP response to the browser.

This is not the page’s main response (200 status code) because the server is yet to begin processing the request it did receive from the browser. This is the early Hint, and as I said in the definition of Early Hint, it tells a browser to perform some task by giving it a hint of what resources it will need when it is time to render the page it requested.

So, while the server is busy thinking (i.e. processing the request), the browser performs tasks like preconnecting or preloading the resource in the main response it expects.

When the response finally comes, the browser begins to render the page, and when it comes across a need for a resource, it doesn’t have to make a request for it because it already did that before the main response even arrived. This improves the website speed by reducing the rendering time of the page.

Communication between a server and a browser with an early hint.
Source: Chrome.

Early Hint has proven to improve the core web vitals of a webpage in which it is implemented. Tests show that an Early Hint can reduce your LCP score by 45% if your LCP element is in the Early Hint, and it does the same for other metrics.

Note: Without an Early Hint, your browser is idle during the Server Think-Time, but with an Early Hint, that time is put to use.

Now you know how the early hint works and its positive impact on your website, let me show you some examples of an Early Hint so you know what an early hint looks like and how to implement them in your server.

Examples of Early Hint.

HTTP/1.1 103 Early Hints
Link: </frog.webp>; rel=preload; as=image
Link: </style.css>; rel=preload; as= style

The above code sample is an example of an Early Hint sent by a server to a browser. As I said earlier, Early Hints use the 103 status code, which is why it is sometimes called 103 Early Hints.

In the example above, the server tells the browser to preload frog.webp, which is the URI of an image, and style.css, which is the URI of a stylesheet, while it is busy preparing the main 200 OK response.

These two resources are used in the webpage’s content, and the browser will need them when rendering the page. When that time comes, the browser can render the image and the stylesheet faster because it has preloaded them upfront.

Note: The Early Hint makes use of the Link Header to perform any task on a Uniform Resource Identifier (URI).

The Link Header is usually placed in an HTTP Response Header that comes with the main response, but the best way to use it for better performance is to place it in an Early Hint since the browser gets to act on it on time.

The Example of Early Hint I showed you above included just two resources, but you can decide to include as many resources as you need to as long as they will be used in the main 200 status code response.

It is important to know that there are resources that can’t be added in an Early Hint, and I will show you what these resources are soon but for now, let me show you how to implement an Early Hint in your HTTP Server.

When Do I need to Implement An Early Hint?

Before I show you how to implement an Early Hint in your server, take note of this: If your server can serve a user browser with the main 200 response immediately after it receives the request, then there is no need for you to implement the 103 Early Hint as the server might end of sending both the 103 and 200 response at the same time which is of no use.

If this is the case, consider using the Link Header directly in the main HTTP Response Header or use the <link> element in your <head> element. Either of these will help you perform the same tasks like preload, preconnect, and so on.

But if your server needs some time to process the requests sent to it by the browser, only then does it make sense to implement an early Hint and put to use the time that the server spends processing the request.

How To Implement Early Hint In HTTP Servers.

Early Hint is fully supported in both Apache and H2O HTTP Servers, and here is how to implement it in them.

Implementing Early Hint in Apache:

You can use the Early Hint via the mod_http2, but you must first enable it in your Apache server using this:

H2EarlyHints on

This will turn on this feature as it is not enabled by default. Early Hint is used as an alternative to Server Push in Apache, and so you have to use the directive H2PushResource to send an Early Hint

<Location /xxx.html>
               H2PushResource /xxx.css
               H2PushResource /xxx.js
               H2PushResource /xxx.png
</Location>

This will send an Early Hint for the resources xxx.css, xxx.js, and xxx.png to your user’s browser immediately after your server receives their request.

Implementing Early Hint in H2O:

Implementing early Hint in H2O can be done in two ways:

1. You can use the header directives with when: early.

paths:
  /:
    headers.add:
      header:
        - "link: </frog.webp>; rel=preload"
        - "link: </style.css>; rel=preload"
        - "link: </ index.js>; rel=preload"
      when: early
    file.dir: /path/to/doc_root

2. You can also use mruby and then add env[‘rack.early_hints'].

paths:
  /:
    mruby.handler: |
      proc {|env|
        env['rack.early_hints'].call({'link' => "</frog.jpg>; rel=preload\n</style.css>; rel=preload\n</index.js>; rel=preload"})
        sleep 1	
        [200, {}, ["hello"]]
      }

Whichever way you use, H2O will work on it and send a hint telling a browser to preload the resource in the Hint.

How To Implement Early Hint With A CDN.

The easiest way to implement the 103 Early Hint on your website is through a CDN, but as of the time I wrote this article, there are only two CDNs that support Early Hint, and they are:

  1. Cloudflare.
  2. Fastly.

Enabling Early Hint In Cloudflare:

To enable 103 Early Hint in Cloudflare, you first have to log in, open your Cloudflare dashboard, and then select your domain.

Click Speed and then Optimization; there, you will find Optimized Delivery. This is where you can enable the Early Hint.

When it is enabled, Cloudflare will convert all resources in the Link Header or <link> element with preconnect and preload to the Early Hints.

Enabling Early Hint In Fastly:

To enable 103 Early Hint in Fastly, you have to use the experimental h2.early_hints in the VCL.

sub vcl_recv {
 if (req.url ~ "^/fiddle/") {
   h2.early_hints("link: </images/early.webp>; rel=preload", "link: </images/icons/vitalfrog.svg>; rel=preload", "link: </images/icons/logo.svg>; rel=preload");
 }
}

This sends an Early Hint for the three images immediately Fastly receives a request from a browser.

Early Hint Browser Support.

As of the time of writing this article, Early Hint is only supported in Chrome 103, and this support was added in June 2022.

I believe other browsers will support this soon as more developers begin to demand it, but for now, Chrome only supports the use of Early Hint with preload and preconnect only; that is, prefetch is not yet supported.

Chrome does not currently support iframe resources also, but the Chrome dev team promised to work on that depending on the interest of the community.

What Resource Should I Include in The Early Hint?

Now you know how to implement the Early Hint in your server, it is essential for you to know that there are some resources used in your webpage that cannot be added in the Early Hint, and I will cover them in this section.

Here are the resources that you can add to your Early Hint:

1. Resources in your Link Header and <link> element:

When implementing the Early Hint in your server (or CDN if you use one), the very first resource you want to consider adding are those you have in your Link Header (in the HTTP Response Header) or <link> element (in the HTML payload).

These resources are in your Link Header or <link> element because you want a browser to perform some task on them as soon as possible, and this can be done quicker if they are in the Early Hint.

If you are making use of Cloudflare, it automatically helps you convert your Link Header and <link> elements into an Early Hint, but for the rest, you would have to do this yourself.

Note: For now, you can only include those with preload and preconnect because that is what Chrome supports. But I believe this will improve soon.

2. The LCP Element:

Another resource you need to include in your Early Hint is the Largest Contentful Paint element. To improve your LCP score, you need a browser to render your LCP element as soon as possible.

Include the URI of your LCP element in the Early Hint enables a browser to preload it up front and when the time comes to render it, the element is rendered faster.

You can make use of Lighthouse to find out which of your webpage elements is the LCP element and then include it in your Early Hint.

3. Render-Blocking Resource:

Render-Blocking Resources are one of the significant things that affect the performance of a website. These resources include JavaScript, stylesheets, and other resources that block a browser’s main thread for more than 50ms.

Although there are other ways of optimizing these render-blocking resources, another way to do this is to include them in your Early Hint and tell a browser to preload them.

If this is done, the total blocking time of the resources will be reduced, improving your score in most of the web vital metrics.

4. Stable resources:

When picking resources, you want to include in the Early Hint, it is essential to only add stable elements that are not updated frequently. Here is what I mean by this.

103 Early Hints
Link: </main.abcd100.css>; rel=preload; as=style
[...]

In the above 103 Early Hint response, the browser is asked to preload main.abcd100.css as a stylesheet. This doesn’t seem right because main.abcd100.css is not stable and is updated frequently. By the time the server is done thinking and sends the main 200 response, here is what it looks like:

200 OK
[...]
<HTML>
<head>
   <title>Example</title>
   <link rel="stylesheet" href="/main.abcd105.css">

The resource required now is main.abcd105.css which is five versions ahead of what you asked the browser to preload. The main.abcd100.css preload earlier is not what the browser needs, so it will have to request main.abcd105.css, and the Early Hint was a waste.

So when including resources in the Early Hint, you want to go for resources that are independent of the main response and are stable.

Impact Of Early Hint On Your Core Web Vitals.

I know I did mention how 103 Early Hint can improve a website’s performance, but I decide to discuss this better and show you clear examples using the core web vitals.

To do this, I will be showing you an experiment made by Arjen Karel, a web performance Engineer, who made use of Lighthouse to mention the performance of a website before and after implementing an Early Hint.

First, he discovered the LCP element of a webpage, an image, and added the URI for that image in an Early Hint.

HTTP/1.1 103 Early Hints
Link: </image.webp>; rel=preload; as=image

He then tested the performance of the webpage, and this was the result:

Lighthouse test with and without early hint.
Source: corewebvitals.io

The LCP score improved from 1.5s to 1.1s, and the TBT score improved from 20ms to 10ms using an Early Hint.

This was also done on another webpage, but this time he did not only add an image to the Early Hint; he included a CSS file.

HTTP/1.1 103 Early Hints
Link: </image.webp>; rel=preload; as=image
Link: </style.css>; rel=preload; as=style

After adding this, he tested the performance with Lighthouse, and here is the result.

Lighthouse test with and without early hint.
Source: corewebvitals.io

The FCP and Speed Index score improved from 1.6s to 1.4s, the LCP score improved from 3.2s to 20s, and the TTI score improved from 1.6s to 1.4s.

This is just an example of an Early Hint’s positive impact on your website if implemented.

Conclusion.

Early Hint enables you to improve the way your server communicates with a user’s browser by giving the browser hints on what it needs to preload or preconnect while it awaits the response to its request.

This can significantly improve your website speed and core web vitals if well implemented with the right resources, and that is why I did show you the right resource to be added in an Early Hint.

Although, Early Hint is only supported in Chrome 103, implementing it is worth it because Chrome has the largest web browser market share, and about 60% of your user are using this browser.

The easiest way to implement Early Hint is with a CDN; you can do this in Cloudflare with just a click of a button. You can also implement this directly from your Server if it supports it.

Even while working with Early Hint, you can also make use of VitalFrog Performance API to automatically test the performance of your website right in your CI/CD, so you get to reduce your debugging time.

Improve your website performance with Early Hint.