The goal of Client Hints is to provide a framework for a browser when informing the server about the context in which a web experience is provided.
HTTP Client Hints are a proposed set of HTTP Header Fields for proactive content negotiation in the Hypertext Transfer Protocol. The client can advertise information about itself through these fields so the server can determine which resources should be included in its response.
With that information (or hints), the server can provide optimizations that help to improve the web experience, also known as Content Negotiation. For images, a better web experience means faster loading, less data payload, and a streamlined codebase.
Client Hints have inherent value, but can be used together with responsive images syntax to make responsive images less verbose and easier to maintain. With Client Hints, the server side, in this case an image CDN, can resize and optimize the image in real time.
Client Hints have been around for a while – since Chrome 35 in 2015, actually. However, support in most Chrome browsers got partly pulled due to privacy concerns in version 67. As a result, access to Client Hints was limited to certain Chrome versions on Android and first-party origins in other Chrome versions.
Now, finally, Google has enabled Client Hints by default for all devices in Chrome version 84!
Let’s see what’s required to make use of Client Hints.
1) Choose an Image CDN that Supports Client Hints
Not many image CDNs support client hints. Max Firtman did an extensive evaluation of Image CDNs that identified ones that supported client hints. ImageEngine stands out as the best image CDN with full Client Hints support in addition to more advanced features.
ImageEngine works like most CDNs by mapping the origin of the images, typically a web location or an S3 bucket, to a domain name pointing to the CDN address. Sign up for a free trial here. After signing up, trialers will get a dedicated ImageEngine delivery address that looks something like this:
xxxzzz.cdn.imgeng.in. The ImageEngine delivery address can also be customized to one’s own domain by creating a CNAME DNS record.
In the following examples, we will assume that ImageEngine is mapped to
images.example.com in the DNS.
2) Make the Browser Send Client Hints
Now that the trialer has an ImageEngine account with full client hints support, we need to tell the browser to start sending the client hints to ImageEngine. This basically means that the webserver has to reply to a request with two specific HTTP headers. This can be done manually on one’s website, or for example use a plugin if the site is running WordPress.
How the headers are added manually depends on one’s website:
- A hosting provider or CDN probably offers a setting to alter http headers,
- One can add the headers in the code of their site. How this is done depends on the programming language or framework one is using. Try googling “add http headers <your programming language or framework>”
- The hosting provider may run apache and allow users to edit the .htaccess configuration file. One can also add the headers in there.
- Trialers can also add the headers to the markup inside the
<head>element using the http-equiv meta element:
<meta http-equiv="Accept-CH" content="DPR, Width, Viewport-Width">.
Add Accept-CH header
The first header is the Accept-CH header. It tells the browser to start sending client hints:
Accept-CH: viewport-width, width, dpr
Add the Feature-Policy header
At the time of writing, the mechanism for delegating Client Hints to 3rd parties is named Feature Policies. However, it’s about to be renamed to Permission Policies.
Then, to make sure the Client Hints are sent along with the image requests to the ImageEngine delivery address obtained in step 1, this feature policy header must be added to server responses as well.
A Feature / Permission policy is a HTTP header specifying which origins (domains) have access to which browser features.
Feature-Policy: ch-viewport-width https://images.example.com;ch-width https://images.example.com;ch-dpr https://images.example.com;ch-device-memory https://images.example.com;ch-rtt https://images.example.com;ch-ect https://images.example.com;ch-downlink https://images.example.com
example.com must be replaced with the actual address refering to ImageEngine whether it’s the generic
xxxzzz.cdn.imgeng.in-type or your customized delivery address.
Pitfall 1: Note the
ch- prefix. The notation is
Pitfall 2: Use lowercase! Even if docs and examples say, for example,
Accept-CH: DPR, make sure to use
ch-dpr in the policy header!
accept-ch and feature-policy header are set, the response from the server will look something like the screen capture above.
3) Set Sizes Attribute
Last, but not least, the
<img> elements in the markup must be updated.
Most important, the src of the
<img> element must point to the ImageEngine delivery address. Make sure this is the same address used in step 1 and mentioned in the feature-policy header in step 2.
Next, add the sizes attribute to the
<img> elements. sizes is a part of the responsive images syntax which enable the browser to calculate the specific pixel size an image is displayed at. This size is sent to the image CDN in the width client hint.
<img src="https://images.example.com/test.jpg" sizes="200px" width="200px" alt="image">
If the width set in CSS or width attribute is known, one can “retrofit” responsive images by copying that value into sizes.
When these small changes have been made to the
<img> element, the request to ImageEngine for images will contain the client hints like illustrated in the screen capture above. The “width” header tells ImageEngine the exact size the image needs to be to fit perfectly on the web page.
Enjoy Pixel-Perfect Images
Now, if tested in a supporting browser, like Chrome version 84 and below, the client hints should be flowing through to
<img> element is short and concise, and is rigged to provide even better adapted responsive images than a classic client-side implementation without client hints would. Less code, no need to produce multiple sizes of the images on your web server and the resource selection is still made by the browser but served by the image CDN. Best from both worlds!
Trialers can see the plumbing in action in this reference implementation on glitch.com. Make sure to test this in Chrome version 84 or newer!
By using an image CDN like ImageEngine that supports client hints, sites will never serve bigger images than necessary when the steps above are followed. Additionally, as a bonus, ImageEngine will also optimize and convert images between formats like WebP, JPEG2000 and MP4 in addition to the more common image formats.
Additionally, the examples above contain a few network- or connectivity-related Client Hints. ImageEngine may also optimize images according to this information.
What about browsers not supporting Client Hints? ImageEngine will still optimize and resize images thanks to advanced device detection at the CDN edge. This way, all devices and browsers will always get appropriately sized images.
ImageEngine offers a free trial, and anyone can sign up here to start implementing client hints on their website.
You can support CSS-Tricks by being an MVP Supporter.