sxg-rs is a set of tools for generating signed exchanges at serve time:
cloudflare_worker
runs on Cloudflare Workers.fastly_compute
runs on Fastly Compute@Edge.sxg_rs
is the Rust library that drives both, and could be used as a basis for other serverless platforms.
These tools enable sites to be prefetched from Google Search in order to improve their Largest Contentful Paint, one of the Core Web Vitals.
After installing, take the following steps.
After installing, you may want to verify and monitor the results.
The worker contains some HTML processors. To activate them, explicitly label the character encoding as UTF-8, either via:
Content-Type: text/html;charset=utf-8
or via:
<meta charset=utf-8>
LCP can be further improved by instructing Google Search to prefetch render-critical subresources for the page.
Add a preload link tag to the page, such as:
<link rel=preload as=image href="/foo.png">
sxg-rs will automatically convert these link tags into Link headers as needed for SXG
subresource
substitution.
This uses a form of subresource integrity that includes HTTP headers. sxg-rs
tries to ensure a static integrity value by stripping many noisy HTTP headers
(like Date) for signed subresources, but you may need to list additional ones
in the strip_response_headers
config param.
To confirm it is working, run:
$ go install github.com/WICG/webpackage/go/signedexchange/cmd/dump-signedexchange@latest
$ dump-signedexchange -uri "$HTML_URL" -payload=false | grep Link
and verify that there is a rel=allowed-alt-sxg
whose header-integrity
matches the output of:
$ dump-signedexchange -uri "$SUBRESOURCE_URL" -headerIntegrity
SXG preloading requires that the subresource is also an SXG. This worker assumes only same-origin resources are SXG, so its automatic logic is limited to those. You can manually support cross-origin subresources by adding the appropriate Link header as specified.
There are two syntaxes for behavior that happens only when the page is viewed as an SXG. If you write:
<script data-issxg-var>window.isSXG=false</script>
then its inner content will be replaced by window.isSXG=true
in an SXG. This
could be used as a custom dimension by which to slice web analytics, or as a
cue to fetch a fresh CSRF token.
If you write:
<template data-sxg-only>...</template>
then in an SXG, its inner content will be "unwrapped" out of the template and thus activated, and when non-SXG it will be deleted. Since SXGs can't Vary by Cookie, this could be used to add lazy-loaded personalization to the SXG, while not adding unnecesary bytes to the non-SXG.
Optionally, preview the results in the browser:
- In development, set Chrome flags to allow the certificate.
- Use an extension such as
ModHeader
to set the
Accept
header totext/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
(equivalent to what Googlebot sends). - Explore the results in the DevTools Network tab.