Skip to content

Optimisation des fonts

Ce guide explique comment optimiser une font pour le web : la compresser, la convertir en WOFF2 et surtout supprimer les glyphes (caractères) inutiles

Cas typique : sur le projet Buchard, la font contenait tous les caractères bengali (langue du Bangladesh/Inde, pourquoi ? bonne question) alors qu'ils n'étaient jamais utilisés. Résultat : une font inutilement lourde (~400 KB avant et 107 KB après)

L'objectif est de réduire drastiquement le poids des fonts en ne gardant que les caractères réellement utilisés, tout en conservant un rendu identique côté utilisateur.

1. Installation des outils

Python (version 3)

bash
py -3 -m pip install fonttools brotli

2. Inspecter une font (voir ce qu'elle contient)

Convertir en XML (lisible)

bash
py -3 -m fontTools.ttx -o font.ttx font.ttf

Lister les glyphs (caractères)

bash
findstr "<map code" font.ttx

Chaque ligne correspond à un caractère Unicode. Exemple :

<map code="0x41" name="A"/>

3. Comprendre les ranges Unicode

Une range Unicode est une plage de caractères.

Exemple :

U+0020-007E

Correspond à :

  • lettres A-Z / a-z
  • chiffres
  • ponctuation basique

Ranges utiles pour le web

RangeContenu
U+0020-007EASCII
U+00A0-00FFLatin étendu (accents)
U+20ACsymbole €

4. Comment trouver les ranges Unicode

Méthode 1 : sites officiels

Exemple :

  • Bengali => U+0980-U+09FF

Méthode 2 : analyser la font (TTX)

Dans font.ttx, chercher :

<map code="0x985" name="VowelA.bn"/>

Indices utiles :

  • .bn => Bengali
  • .ar => arabe
  • .cy => cyrillique

Les codes hex permettent de repérer les ranges :

  • 0x0980-0x09FF => Bengali

Méthode 3 : détecter automatiquement

bash
py -3 - <<EOF
from fontTools.ttLib import TTFont

font = TTFont("font.ttf")
cmap = font["cmap"].getBestCmap()

codes = sorted(cmap.keys())
print("Min:", hex(min(codes)))
print("Max:", hex(max(codes)))
EOF

Permet de voir rapidement jusqu'où va la font.


5. Comment choisir les bonnes ranges

Se poser la question :

Quelles langues utilise mon site ?

Cas typiques

Site FR

U+0020-007E,U+00A0-00FF,U+20AC

Site européen

U+0020-007E,U+00A0-00FF,U+0100-017F

Multi-langue

Adapter selon besoins


6. Supprimer des langues inutiles

Exemple : enlever Bengali

Range :

U+0980-U+09FF

Commande :

bash
py -3 -m fontTools.subset font.ttf ^
  --output-file=font-nobengali.woff2 ^
  --flavor=woff2 ^
  --unicodes="U+0000-097F,U+0A00-10FFFF"

7. Subset optimal (web standard)

bash
py -3 -m fontTools.subset font.ttf ^
  --output-file=font-clean.woff2 ^
  --flavor=woff2 ^
  --unicodes="U+0020-007E,U+00A0-00FF,U+20AC" ^
  --layout-features='*' ^
  --no-hinting

Options :

  • --flavor=woff2 : format web compressé
  • --no-hinting : réduit la taille
  • --layout-features='*' : conserve les ligatures utiles

8. Conversion et compression TTF => WOFF2

Méthode 1 : fonttools (Python)

bash
py -3 -m fontTools.ttLib.woff2 compress font.ttf

Méthode 2 : outil officiel Google (woff2)

Projet : https://github.com/google/woff2

Installation (Windows)

Option simple :

  • télécharger les binaires précompilés (release GitHub)

Ou compiler avec CMake si nécessaire.

Utilisation

bash
woff2_compress font.ttf

Résultat :

font.woff2

Décompression (inverse)

bash
woff2_decompress font.woff2

9. Vérifier le résultat

bash
dir *.woff2

Résultat typique :

  • original : 500 KB+
  • optimisé : 40-80 KB

10. Bonnes pratiques

  • toujours utiliser WOFF2
  • toujours faire un subset
  • éviter les fonts multi-langues non filtrées
  • tester visuellement après optimisation

Contributors

The avatar of contributor named as Clément Favre Clément Favre

Changelog