Comment diviser par 10 le poids de vos polices grâce au subsetting
La majorité des sites web utilisent des polices personnalisées que l'on retrouve souvent sur Google Fonts. Comme vous le savez probablement, vous devez télécharger autant de fichiers que de graisses. En effet, si vous avez besoin de 4 graisses et leur version italique, vous aurez besoin de 8 fichiers (8 requêtes HTTP, 8 fichiers de 150ko en TTF, etc).
Nous allons voir comment réduire de plus de 90% le poids (et améliorer votre CLS (Cumulative Layout Shift)) de vos polices variables en embarquant la totalité des graisses au passage.
On va prendre Roboto comme exemple et pour comparer les performances, nous allons convertir les TTF en WOFF2 pour avoir une référence avec des fontes statiques optimisées.
| Fonte statique | TTF (source) | WOFF2 (conversion) |
|---|---|---|
| Roboto-Regular | 156 Ko | 68 Ko |
| Roboto-Bold | 157 Ko | 70 Ko |
| Roboto-Light | 156 Ko | 68 Ko |
| Roboto-Black | 157 Ko | 69 Ko |
| Roboto-Italic | 162 Ko | 74 Ko |
| Roboto-BoldItalic | 163 Ko | 76 Ko |
| Roboto-LightItalic | 162 Ko | 74 Ko |
| Roboto-BlackItalic | 163 Ko | 75 Ko |
| TOTAL | 1,276 Mo | 0,574 Mo |
On peut voir que le poids des polices d'un site est comparable aux chargements d'une dizaine d'images.
La conversion de TTF à WOFF2 apporte un gain de 55% mais ce n'est pas suffisant.
Voyons ce que cela peut donner si nous utilisons les polices variables à la place.
Ce qu'est vraiment une fonte variable
Une fonte variable est un fichier unique qui encode plusieurs variations typographiques sur un ou plusieurs axes continus. L'axe wght (graisse) est le plus courant : il permet d'aller de Thin (100) à Black (900) sans avoir à télécharger neuf fichiers distincts.
D'autres axes existent : ital (italique), wdth (chasse), opsz (taille optique), ou des axes propriétaires. Une fonte comme Roboto Flex en combine une douzaine.
Concrètement, un fichier variable TTF contient :
- tous les glyphes pour chaque point de l'axe,
- des tables de variations (GVAR, HVAR, MVAR...),
- les métadonnées de toutes les instances nommées.
Un seul fichier pour toutes les graisses (et bien plus) mais à quel prix ?
| Fonte variable | TTF (source) | WOFF2 (conversion) |
|---|---|---|
| Roboto-VariableFont_wdth,wght | 477 Ko | 216 Ko |
| roboto-italic-variablefont-wdth,wght | 518 Ko | 249 Ko |
| TOTAL | 0,995 Mo | 0,465 Mo |
La version variable nous permet de réduire légèrement le poids des fontes dans un cas où l'on utilise 4 graisses ou plus. Dans les autres cas, c'est l'inverse, le coût de la fonte variable n'est pas intéressant.
Le vrai problème : les glyphes inutiles
Une fonte Google Fonts couvre souvent des centaines de systèmes d'écriture. Roboto, par exemple, inclut le latin de base, le latin étendu, le cyrillique, le vietnamien, le grec... Autant de glyphes dont un site français n'a absolument pas besoin.
Le subsetting consiste à extraire uniquement les glyphes correspondant aux caractères réellement utilisés. Pour un site en français ou en anglais, les plages Unicode suivantes couvrent 99,9 % des besoins :
U+0020-007F— Latin de base (ASCII) : lettres, chiffres, ponctuation couranteU+00A0-00FF— Latin-1 Supplement : accents français, symboles monétaires (€, £), marques (©, ®, ™)U+0152-0153— Une portion du Latin Extended-A : uniquement le "œ" et "Œ"
Tout le reste ? Supprimé. Le gain est immédiat et drastique.
| Fonte variable | TTF (source) | WOFF2 | WOFF2 Latin |
|---|---|---|---|
| Roboto-VariableFont_wdth,wght | 477 Ko | 216 Ko | 77 Ko |
| roboto-italic-variablefont-wdth,wght | 518 Ko | 249 Ko | 89 Ko |
| TOTAL | 0,995 Mo | 0,465 Mo | 0,166 Mo |
Comparaison avec des Google Fonts populaires
Comparons maintenant ce que ça donne sur un échantillon de 5 Google Fonts variables populaires.
| Fonte | TTF variable (source) | WOFF2 complet | WOFF2 Latin | Gain |
|---|---|---|---|---|
| Roboto | 477 Ko | 217 Ko | 77 Ko | -84 % |
| Open Sans | 518 Ko | 274 Ko | 83 Ko | -84 % |
| Inter | 855 Ko | 341 Ko | 85 Ko | -90 % |
| Montserrat | 673 Ko | 202 Ko | 51 Ko | -92 % |
| Roboto Flex | 1646 Ko | 730 Ko | 288 Ko | -82 % |
Télécharger les fontes optimisées
Comme je suis cool, je vous donne les quelques fontes que j'ai déjà allégées pour que vous puissiez les télécharger et les utiliser sur vos propres sites :
Ces versions ultra-optimisées vont vous permettre d'accélérer le chargement de votre site et optimiser votre CLS (Cumulative Layout Shift).
Créez vos subsets de fontes
L'outil de référence est fontTools, la bibliothèque Python maintenue par Google et utilisée en interne pour produire les fontes Google Fonts elles-mêmes.
Installation :
sudo apt install python3-fonttools python3-brotli
ou alors
pip3 install fonttools brotli
La commande de subset, telle qu'utilisée sur ce projet :
python3 -m fontTools.subset "resources/fonts/Lexend-VariableFont_wght.ttf" \
--unicodes="U+0020-007F,U+00A0-00FF,U+0152-0153" \
--flavor=woff2 \
--output-file="public/fonts/lexend-variablefont-wght.woff2" \
--layout-features="*" \
--name-IDs="*"
Ce que fait chaque option :
--unicodes: les plages de caractères à conserver (tout le reste est jeté)--flavor=woff2: compression WOFF2 directement en sortie, pas besoin d'étape intermédiaire--layout-features="*": conserve toutes les fonctionnalités OpenType (ligatures, kerning, etc.)--name-IDs="*": conserve les métadonnées de la fonte (nécessaire pour les instances nommées)
Automatisé dans un makefile, ça donne une cible font-subset qu'on appelle au build. Un seul appel pour traiter toutes les fontes du dossier resources/fonts/ :
font-subset: ## Génère un subset woff2 pour chaque fonte de resources/fonts/ vers public/fonts/
@for font in resources/fonts/*; do \
name=$$(basename "$$font" | sed 's/\.[^.]*$$//' | sed 's/_/-/g' | tr '[:upper:]' '[:lower:]'); \
output="public/fonts/$$name.woff2"; \
python3 -m fontTools.subset "$$font" \
--unicodes="U+0020-007F,U+00A0-00FF" \
--flavor=woff2 \
--output-file="$$output" \
--layout-features="*" \
--name-IDs="*"; \
done
Optimisez votre déclaration @font-face
Maintenant que nous avons optimisé le fichier, nous pouvons aussi optimiser son chargement dans la déclaration @font-face pour améliorer la performance perçue.
<!-- Preload : le navigateur télécharge la fonte dès le parsing du <head> -->
<link rel="preload" href="/fonts/lexend-variablefont-wght.woff2" as="font" type="font/woff2" crossorigin>
<style>
@font-face {
font-family: 'Lexend';
src: url('/fonts/lexend-variablefont-wght.woff2') format('woff2');
font-weight: 100 900; /* toutes les graisses disponibles sur l'axe wght */
font-style: normal;
font-display: optional; /* chargement lazy */
}
/* Fallback calibré pour zéro layout shift */
@font-face {
font-family: 'Lexend Fallback';
src: local('Arial'); /* on affiche un arial ajusté en attendant Lexend */
ascent-override: 90%;
descent-override: 22%;
line-gap-override: 0%;
size-adjust: 107%;
}
</style>
A vous de faire le ménage dans vos fontes !
La recette est simple :
- Une fonte variable TTF dans
resources/fonts/ - Un
make font-subsetau build avec fontTools → fichier WOFF2 subseté danspublic/fonts/ - Un
@font-facecorrectement déclaré avecfont-weight: 100 900etfont-display: optional - Un fallback calibré avec
ascent-override,descent-overrideetsize-adjust
Le résultat sur uxcode : Lexend à 28 KB, chargée en une seule requête, avec toutes les graisses disponibles de 100 à 900, sans flash typographique, sans layout shift.
Le résultat ? Une typographie riche, une requête unique de moins de 30 Ko, et une bonne pratique de plus pour un score Lighthouse qui vise les 100%.
C'est l'approche standard pour tout projet web sérieux en 2026.