Optimizing Fonts
donovanglover opened this issue · comments
Feature Request
Summary
I noticed that fonts total to 822 KB when loading a blog post, which is about 3/4 the size of a page.
The fonts on google-webfonts-helper are generally smaller, so I assume some optimization can be done to significantly reduce the file sizes.
Motivation
Faster load times. Only load what's used.
Detailed Description
- How many font weights are needed?
- What charsets are used?
Additional Context
Should users be able to customize the fonts used? Specifying fonts can be useful especially if system fonts are preferred.
I noticed that tabi takes advantage of the modern variable fonts feature in CSS, so it may be difficult to use non-variable fonts like the 400/600/700 ones.
I also saw the font charsets with FontForge. Overall, I think optimizations can be done on a case-by-case basis and feel like the current fonts are already good for a majority of users.
I'm interested in reducing the size of the resources, so I'll definitely look into some options in regards to fonts.
The google-webfonts-helper
link above is pretty good when it comes to .woff2
sizes. The biggest downside is that existing font-weight
s would have to be rounded to the nearest 100.
Potential advantages include more consistent fonts across a variety of browsers. qutebrowser has trouble showing some of the current font weights, for example.
I can't use the webfonts helper as I'm using the latest Inter version, not available in Google Fonts. Here's what I did:
Coding Font
For the mono/code font (Cascadia Code), I've ran:
pyftsubset CascadiaCode-SemiLight.woff2 \
--layout-features="kern,liga" \
--desubroutinize \
--unicodes=U+0020-007E,U+00A0-00FF \
--flavor=woff2 \
--output-file=font_with_accents.woff2
This compresses the font file from 133KB to 13KB. The font includes:
- Basic ASCII characters (
U+0020-007E
): Covers English, the Latin-1 Supplement, and most coding symbols. - Ligatures & kerning.
I believe this subset should be sufficient for code formatting in the vast majority of use-cases, satisfying 99.9% of users.
Serif & Sans Serif
For the serif and sans-serif fonts, I've ran:
pyftsubset SourceSerif4Variable-Roman.otf.woff2 \
--layout-features="kern,liga" \
--desubroutinize \
--unicodes="U+0020-00FF,U+0100-024F,U+1E00-1EFF,\
U+0400-052F,U+0391-03D6,\
U+4E00-9FFF,U+3400-4DBF,U+20000-2A6DF,\
U+3040-309F,U+30A0-30FF,\
U+0600-06FF,U+2000-206F" \
--flavor=woff2 \
--output-file=optimized_font.woff2
pyftsubset InterVariable.woff2 \
--layout-features="kern,liga,calt" \
--desubroutinize \
--unicodes="U+0020-00FF,U+0100-024F,U+1E00-1EFF,\
U+0400-052F,U+0391-03D6,\
U+4E00-9FFF,U+3400-4DBF,U+20000-2A6DF,\
U+3040-309F,U+30A0-30FF,\
U+0600-06FF,U+2000-206F,U+2190-21FF" \
--flavor=woff2 \
--output-file=optimized_font_with_kerning.woff2
This subset includes:
- Latin and Latin Extended (
U+0020-00FF, U+0100-024F, U+1E00-1EFF
): Covers most European languages including those with diacritics and accents. - Cyrillic (
U+0400-052F
): Covers languages like Russian and Ukrainian. - Greek (
U+0391-03D6
): Includes basic Greek characters. - Chinese (
U+4E00-9FFF, U+3400-4DBF, U+20000-2A6DF
): A broad set for Simplified and Traditional Chinese. - Japanese (
U+3040-309F, U+30A0-30FF
): Includes Hiragana and Katakana. - Arabic (
U+0600-06FF
): Basic Arabic script. - General Punctuation (
U+2000-206F
): Covers a range of punctuation marks including the bullet point, dashes, and various kinds of spaces. - For Inter: arrows.
This configuration should cover a broad spectrum of languages and scripts, aiming to satisfy most use-cases.
This brings the sans serif font, Inter-4.0-beta9h, from 326KB to 168KB.
The serif font, Source Serif 4, went from to 429KB to 253KB.
Aggregated, this takes the font sizes from 803KB to 434; almost half of the original size.
I will be doing a PR with these changes soon.
That sounds awesome! Thanks for working on this!