topics: css , http/2 (tidbit)

Web Fonts and HTTP/2 Server Push

Web fonts used via CSS can often result in a flickering effect when a web page loads without any previously cached CSS or font assets. Often there are several requests that happen sequentially to first instruct the browser that a Web Font is to be used and then provide the required font artifact(s).

This may look like:

  browser                   server      
    |                         |
    | - - GET index.html - - >|
    |                         |
    |< - - - index.html  - - -|
    |                         |
    | - - GET style.css  - - >|
    |                         |
    |< - - - style.css   - - -|
    |                         |
    | - - GET font.woff  - - >|
    |                         |
    |< - - - font.woff   - - -|

HTTP/2 Server Push

HTTP/2 Server Push is a mechanism that allows for resources to be preemptively pushed to a compliant client or browser.

Web servers that support HTTP/2 Server Push typically provide a mechanism to define that for given request characteristics the response should provide streams to the client for additional content multiplexed over the single TCP connection established to make the request. Streams may be closed by the client should the client decide to do so without having transferred the content of the files. This allows for a client to decide based on any currently cached assets if the stream should be accepted and completed, reducing the risk of aimlessly streaming multiple files with every request.

Generally fewer connections are easier for a web server to handle, and the parallel transfer of assets faster for the client to receive.

  browser                   server
    |                         |
    | - - GET index.html - - >|
    |                         |
    |< - - - index.html  - - -|
    |                         |
    |    < - style.css   - - -|
    |                         |
    |    < - font.woff   - - -|

A Link HTML element specifies how an HTML document is related to supplementary resources.

For example:

<link href="/style.css" rel="stylesheet" />

The Link Header Field performs the same purpose but as a header in the response.

For example:

Link: </style.css>; rel=preload; as=style

The Link header can be used by an application running in a server push capable web server context to instruct the web server to initiate streams with the assets as defined in the header. The Link header can also be understood by any HTTP/2 capable caching layers in use that have access to the unencrypted response mid-flight, such as a CDN.

Multiple assets can be specified in a single Link header. Alternatively multiple Link headers can be used.

Link: </style.css>; rel=preload; as=style, </font.woff2>; rel=preload; as=font

vs

Link: </style.css>; rel=preload; as=style
Link: </font.woff2>; rel=preload; as=font

Cloudflare

Cloudflare provides support for HTTP/2 Server Push via the Link Header. If a client makes an HTTP/2 request, Cloudflare is able to introspect any Link headers passed from the original content (origin) web server, creating the opportunity for the client to accept multiplexed assets in addition to content explicitly requested. If coupled with an edge caching strategy and client caching policies for the relevant artifacts, there is the potential for fast and efficient responses, minimising the opportunity for issues such as the Web Font flickering effect.

Considerations

HTTP/2 Server Push for Web Fonts is potentially complicated by differing browser implementations as well as font fetching requirements. Testing in modern (late 2019) versions of Safari, Chrome and Firefox demonstrate expected behaviour (example) with some concerns expressed in a popular 2017 blog post now seemingly resolved.