By Shehab Waleed, Founder, Cairo Studio 2 min read
In August we moved our fonts off Google Fonts and onto our own server. For IBM Plex Sans we took the weights we use, 300 to 700, and saved the file for each one, for the Latin and Latin Extended subsets. Ten files, ten @font-face rules, and it worked.
Two months later, during a performance pass, we listed the font folder by size. Every Latin file was exactly 40,240 bytes. Every Latin Extended file was 25,868. Different weights of a static font are never the same size to the byte.
md5 -q ibm-plex-sans-*-latin.woff2 | sort | uniq -c
5 d28498895ed7050c37c94ddd026a4670
Five weights, one file, saved five times.
Why the files were identical
Google Fonts serves IBM Plex Sans as a variable font, one file that contains every weight. Its CSS still writes a separate @font-face for each weight you ask for, and each rule points at the same URL. We fetched that CSS again to check: five weights, one URL.
When the URL is shared, the browser downloads the file once and reuses it. Our script saved each rule to its own file name, so the browser saw five different URLs and treated them as five fonts. A page that used three weights downloaded the same 40KB three times.
One rule with a range
A variable font can declare the whole range it covers in a single rule.
@font-face {
font-family: 'IBM Plex Sans';
src: url('/fonts/ibm-plex-sans-latin.woff2') format('woff2');
font-weight: 300 700;
font-display: swap;
}We kept one rule per subset, each with its unicode-range, so a page only downloads Latin Extended when it uses those characters. Every weight from 300 to 700 now comes from one download.
Where else this happens
Any tool that turns the Google Fonts CSS into local files can do this, if it names files by weight instead of by URL. Check the sizes after you download. Identical sizes across weights mean a variable font, and one rule with a range is all it needs.
We found it in the same pass as a much bigger problem: the test machine with no graphics card. Small wins like this one only show up once you read the network list line by line.
