En une phrase
La conversion et le subsetting de polices, c'est comme faire sa valise pour un week-end : au lieu de se trimballer une valise de 6 000 caractères blindée de scripts cyrilliques et de dingbats qui ne vous serviront jamais, vous ne prenez que les lettres exactes dont vous avez besoin dans un sac à dos ultra-compressé et taillé pour le web.
Le problème que ça résout
Si vous faisiez des sites web en 2005, votre palette typographique s'apparentait à une prise d'otages. Vous aviez Arial, Times New Roman, Georgia, Verdana, et peut-être Comic Sans si vous vouliez voir le monde brûler. C'était les polices dites "web-safe" — en gros, on croisait les doigts en espérant qu'elles soient déjà installées sur l'OS de l'utilisateur.
Puis est arrivée la révolution @font-face. Soudain, les designers pouvaient embarquer n'importe quelle police custom. Le web est devenu magnifique, mais il est aussi devenu atrocement lent.
Les polices desktop standards (TrueType ou OpenType) sont taillées pour le print et un support de langue universel. Un seul fichier .ttf peut contenir des milliers de glyphes, gérant l'anglais, le grec, le vietnamien, des symboles mathématiques chelous et vingt variantes de l'esperluette. C'est génial pour un traitement de texte, mais catastrophique pour un navigateur avec une connexion 3G capricieuse. Télécharger un fichier de font de 400 Ko bloque le rendu, provoquant le redoutable "Flash of Unstyled Text" (FOUT) ou pire, le "Flash of Invisible Text" (FOIT).
Il nous fallait deux choses pour guérir cette obésité typographique :
- Une meilleure compression pensée spécifiquement pour le web (d'où les formats comme WOFF et WOFF2).
- Le subsetting (ou sous-ensemble), à savoir l'ablation chirurgicale de chaque caractère et table de langage dont un site n'a pas réellement besoin.
Comment ça marche sous le capot
Pour piger comment on fait maigrir les polices, il faut comprendre ce qu'est vraiment un fichier de police. Une police moderne (comme TTF ou OTF) n'est pas juste un dossier de dessins vectoriels. C'est une base de données binaire complexe basée sur le format conteneur SFNT.
L'anatomie d'une police
À l'intérieur d'un conteneur SFNT, la donnée est organisée dans des tables spécifiques :
glyfouCFF: Les dessins vectoriels eux-mêmes (les courbes et les lignes des lettres).cmap: La table des caractères (character map), qui traduit un point Unicode (commeU+0041pour 'A') vers le bon dessin dans la tableglyf.GSUB/GPOS: Les features OpenType avancées comme les ligatures (connecter le 'f' et le 'i') et le kerning (l'espacement entre des paires de lettres spécifiques).name: Les métadonnées comme le nom de la police, le copyright, et les infos du designer.
La magie du Subsetting
Quand on fait un subset d'une font, un parser ouvre ce conteneur SFNT. On lui file une liste de caractères — disons, juste l'alphabet latin basique, les chiffres et la ponctuation courante.
Le parser ne se contente pas de supprimer les dessins vectoriels inutilisés de la table glyf. Il doit reconstruire méticuleusement toute la base de données. Il réécrit la cmap pour virer les points Unicode abandonnés. Il passe au peigne fin les tables GSUB et GPOS, dégageant les paires de kerning pour les lettres disparues, s'assurant que le fichier ne pète pas. Enfin, il recalcule les offsets mémoire pour les headers du fichier.
Une font standard de 300 Ko peut facilement tomber à 15 Ko quand elle est subset pour ne garder que les caractères latins de base.
La guerre des formats : WOFF et WOFF2
Une fois la police subset, c'est l'heure de la compresser.
| Format | Techno de Compression | Le Verdict |
|---|---|---|
| TTF / OTF | Aucune (en général) | Top pour les apps de design desktop. Horrible pour le web. |
| WOFF | Zlib | Le Web Open Font Format original. Bien, mais dépassé. |
| WOFF2 | Brotli | Le standard moderne. Transforme les tables de la font avant de les compresser. |
WOFF2 est le roi incontesté des web fonts. Il ne fait pas juste prendre un TTF pour le zipper. WOFF2 transforme physiquement les tables SFNT — en regroupant notamment les types de data similaires — pour que l'algorithme de compression Brotli sous-jacent puisse trouver des motifs répétés plus longs. Résultat : des fichiers jusqu'à 30 % plus petits que WOFF1, et potentiellement 95 % plus petits que le TTF original si on le combine avec du subsetting.
Lier le tout avec CSS
Une fois que vous avez votre fichier WOFF2 subset et ultra-compressé, vous mettez le navigateur au parfum via CSS. La propriété unicode-range est cruciale ici. Elle dit au navigateur : "Ne télécharge ce fichier que si un caractère sur la page correspond réellement à cette plage."
@font-face {
font-family: 'MyCustomFont';
/* Charge le format ultra-compressé WOFF2 */
src: url('mycustomfont-subset.woff2') format('woff2');
/* Déclenche le téléchargement uniquement si la page utilise des caractères latins basiques */
unicode-range: U+0000-00FF, U+0131, U+0152-0153;
font-display: swap;
}
Histoires vécues
La catastrophe du "Juste une esperluette"
Une petite agence de design créait une landing page pour un resto haut de gamme. La typographie du titre défonçait, surtout parce qu'ils utilisaient une magnifique police cursive uniquement pour l'esperluette (&) dans le nom du resto : "Salt & Ash".
Mais voilà, les scores de perf Lighthouse étaient dans le rouge écarlate. Les devs se sont rendu compte qu'ils forçaient les utilisateurs à télécharger un fichier TTF de 250 Ko juste pour afficher un seul caractère. En passant la font dans un subsetter et en extrayant uniquement le caractère & (Unicode U+0026), ils ont généré un fichier WOFF2 qui pesait le poids ridicule de 800 octets.
La leçon : Ne chargez jamais une famille de polices complète pour des lettrines déco, des icônes ou des caractères isolés. Faites du subsetting agressif.
Le mégaoctet multilingue
Une boîte SaaS a traduit son site marketing pour ses utilisateurs au Japon et en Corée du Sud. Pour garder une cohérence de marque, ils ont embarqué une font CJK (Chinois, Japonais, Coréen) très reconnue. Les polices CJK sont réputées massives car elles contiennent des dizaines de milliers d'idéogrammes. Le fichier faisait 4,5 Mo.
Du jour au lendemain, leurs utilisateurs US et européens devaient attendre des secondes pour que le texte apparaisse, parce que le navigateur téléchargeait 4,5 Mo de caractères asiatiques qu'ils ne verraient jamais. L'équipe technique a réglé ça en subsetant la police master en plusieurs petits "chunks" (un WOFF2 pour le latin basique, un pour les Hiragana/Katakana, etc.) et en les déployant avec des blocs @font-face utilisant des descripteurs unicode-range stricts. Désormais, les navigateurs ne téléchargeaient plus que le chunk latin de 15 Ko pour les utilisateurs anglophones.
La leçon : Utilisez le subsetting et unicode-range pour servir dynamiquement des chunks typo selon les vrais besoins linguistiques de l'utilisateur.
Erreurs classiques et pièges
- Supprimer l'espace par accident : En tapant littéralement les caractères qu'ils veulent subset (ex:
abcdefghijklmnopqrstuvwxyz), les devs oublient souvent d'inclure le caractère espace (U+0020). Sans lui, votre belle font custom fera un fallback sur de l'Arial à chaque espace entre deux mots, donnant un look de lettre de rançon tout à fait terrifiant. - Servir des vieux formats pour rien : Plein de devs génèrent et servent encore des fonts EOT, TTF et SVG dans leur stack CSS "juste au cas où". Ne faites pas ça. WOFF2 est supporté par plus de 97 % des navigateurs dans le monde. Servez du WOFF2, donnez éventuellement du WOFF en fallback pour les antiquités, et arrêtez-vous là.
- Dégager des features OpenType essentielles : Certains outils de subsetting agressifs proposent de zapper les tables
GSUBetGPOSpour gratter quelques kilos-octets. Si votre police dépend de ligatures complexes (comme transformer->en flèche) ou s'appuie massivement sur le kerning pour ne pas être immonde, virer ces tables va massacrer la typo. - Oublier le
font-display: swap: Même un minuscule WOFF2 subset de 12 Ko met quelques millisecondes à se télécharger. Si vous n'incluez pasfont-display: swapdans votre CSS, les navigateurs modernes cacheront totalement votre texte tant que la font n'est pas là. Donnez à vos utilisateurs du texte système à lire pendant que la police custom est en route.
Pourquoi vous devez l'avoir dans votre radar
Les web fonts sont historiquement parmi les pires coupables quand il s'agit de ruiner les Web Vitals. Si vous vous souciez du Largest Contentful Paint (LCP) ou du Cumulative Layout Shift (CLS), vous devez vous soucier de la livraison des fonts.
Vous devriez penser à la conversion et au subsetting au moment précis où vous recevez un fichier .ttf ou .otf d'un designer ou que vous le téléchargez depuis une fonderie. Servir des polices desktop brutes sur le web, c'est l'équivalent de servir un bitmap brut et non compressé de 10 Mo à la place d'un WebP.
En convertissant en WOFF2 et en dégageant les milliers de glyphes que vous n'utilisez pas, vous réduisez les coûts de bande passante, baissez l'empreinte carbone de votre application, et garantissez que votre site est vraiment lisible à la milliseconde où l'utilisateur clique sur votre lien.
Pour aller plus loin
- MDN Web Docs: @font-face - La bible absolue sur l'implémentation de polices custom et la bonne utilisation de
unicode-rangeen CSS. - W3C WOFF2 Specification - La spec technique officielle qui détaille exactement comment WOFF2 transforme et compresse les tables SFNT.
- RFC 7932: Brotli Compressed Data Format - La documentation de l'IETF sur l'algorithme de compression qui donne à WOFF2 ses superpouvoirs.
- Web.dev: Optimize WebFonts - Le guide de référence de Google pour minimiser le payload des web fonts et éviter les layout shifts.
- Google Fonts Knowledge: What is a font? - Une plongée en profondeur dans la structure de la table SFNT et la façon dont les glyphes sont stockés sous le capot.