Skip to content

Instantly share code, notes, and snippets.

@paulirish
Last active April 2, 2024 17:36
Show Gist options
  • Star 19 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save paulirish/d511793a1c3b74b31460 to your computer and use it in GitHub Desktop.
Save paulirish/d511793a1c3b74b31460 to your computer and use it in GitHub Desktop.
webfont performance notes

Just jotting some notes on delivering webfonts performantly…

still an incomplete draft.

Any critical fonts must be requested asap.

Critical fonts are neccessary for the above-the-fold content to be useful. Identify which of the fonts you NEED for the first render, as they get very different treatment vs the others.

You want the network reqs for your critical fonts to start ASAP. ideally the @font-face req is in a style tag, following CRP guidelines

get the network request going

Never be dependent on an external script for any font work.

  • you don't want a @font-face to be in CSS that's included via JS. this is equivalent to JS document.write'ing more JS.

Defer italics, bold, ayptical glyphs

Recommended resources on font loading.

(Basically: If it doesn't have the names Zach, Ilya or Bram attached, raise an eyebrow :)

for those on typekit, use the async kit.

If you're using typekit, then this is a must.

@ithinkihaveacat
Copy link

Re "get the network request going", in some browsers, you can also use the Link header, which Google Fonts uses right now:

$ curl -A "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5X Build/MMB29V) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.95 Mobile Safari/537.36" -s -D - -o /dev/null "https://fonts.googleapis.com/css?family=Source+Code+Pro" | grep Link
Link: <https://fonts.gstatic.com>; rel=preconnect; crossorigin

(In this case the response is text/css, so a header is the only option.)

The AMP boilerplate also includes CSS to hide all content, which is then unhidden by JS when fonts have been given some time to load. (With CSS animation fallback to expose content at 8s, if the JS didn't load or errored out.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment