Réduire la taille de police sur le Web

Ilya Grigorik
Ilya Grigorik
Jeremy Wagner
Jeremy Wagner

La typographie est essentielle à une bonne conception, au branding, à la lisibilité et à l'accessibilité. Les polices Web permettent tout cela et plus encore: le texte est sélectionnable, cliquable, zoomable et compatible avec les écrans haute résolution, ce qui offre un rendu de texte cohérent et net, quelle que soit la taille et la résolution de l'écran. Les WebFonts sont essentielles à une bonne conception, à une bonne expérience utilisateur et à de bonnes performances.

L'optimisation des polices Web est un élément essentiel de la stratégie de performances globale. Chaque police est une ressource supplémentaire, et certaines peuvent bloquer l'affichage du texte. Toutefois, le fait que la page utilise WebFonts ne signifie pas qu'elle doit s'afficher plus lentement. Au contraire, les polices optimisées, associées à une stratégie judicieuse de chargement et d'application sur la page, peuvent contribuer à réduire la taille totale de la page et à améliorer les temps de rendu.

Anatomie d'une police Web

Une police Web est une collection de glyphes, et chaque glyphe est une forme vectorielle qui décrit une lettre ou un symbole. Par conséquent, deux variables simples déterminent la taille d'un fichier de police particulier: la complexité des tracés vectoriels de chaque glyphe et le nombre de glyphes dans une police donnée. Par exemple, Open Sans, l'une des polices WebFonts les plus populaires, contient 897 glyphes, dont des caractères latins, grecs et cyrilliques.

Tableau des glyphes de police

Lorsque vous choisissez une police, il est important de tenir compte des jeux de caractères compatibles. Si vous devez localiser le contenu de votre page dans plusieurs langues, vous devez utiliser une police qui peut offrir une apparence et une expérience cohérentes à vos utilisateurs. Par exemple, la famille de polices Noto de Google vise à prendre en charge toutes les langues du monde. Notez toutefois que la taille totale de Noto, avec toutes les langues incluses, nécessite un téléchargement ZIP de plus de 1,1 Go.

Dans cet article, vous découvrirez comment réduire la taille de fichier de vos polices Web.

Formats de polices Web

Aujourd'hui, deux formats de conteneur de polices sont recommandés sur le Web:

WOFF et WOFF 2.0 sont largement acceptés et compatibles avec tous les navigateurs modernes.

  • Proposez une variante WOFF 2.0 aux navigateurs modernes.
  • Si nécessaire (par exemple, si vous devez toujours prendre en charge Internet Explorer 11), utilisez le WOFF comme solution de secours.
  • Vous pouvez également envisager de ne pas utiliser de polices Web pour les anciens navigateurs et de revenir aux polices du système. Cela peut également être plus performant pour les appareils plus anciens et plus limités.
  • Étant donné que WOFF et WOFF 2.0 couvrent tous les cas de figure pour les navigateurs modernes et anciens encore utilisés, l'utilisation d'EOT et de TTF n'est plus nécessaire et peut entraîner des temps de téléchargement de polices Web plus longs.

Polices Web et compression

WOFF et WOFF 2.0 sont tous deux dotés d'une compression intégrée. La compression interne de WOFF 2.0 utilise Brotli et offre une compression jusqu'à 30% meilleure que WOFF. Pour en savoir plus, consultez le rapport d'évaluation du format WOFF 2.0.

Enfin, notez que certains formats de polices contiennent des métadonnées supplémentaires, telles que des informations sur l'hinting et le crénage, qui peuvent ne pas être nécessaires sur certaines plates-formes. Cela permet d'optimiser davantage la taille des fichiers. Par exemple, Google Fonts gère plus de 30 variantes optimisées pour chaque police, et détecte et fournit automatiquement la variante optimale pour chaque plate-forme et chaque navigateur.

Définir une famille de polices avec @font-face

La règle CSS @font-face vous permet de définir l'emplacement d'une ressource de police particulière, ses caractéristiques de style et les points de code Unicode pour lesquels elle doit être utilisée. Une combinaison de ces déclarations @font-face peut être utilisée pour créer une "famille de polices", que le navigateur utilisera pour évaluer les ressources de polices à télécharger et à appliquer à la page actuelle.

Envisager une police variable

Les polices variables peuvent réduire considérablement la taille de vos polices lorsque vous avez besoin de plusieurs variantes d'une police. Au lieu de devoir charger les styles standard et en gras, ainsi que leurs versions en italique, vous pouvez charger un seul fichier contenant toutes les informations. Toutefois, les tailles de fichiers de polices variables sont plus importantes que celles d'une variante de police individuelle, mais plus petites que la combinaison de plusieurs variantes. Plutôt que d'utiliser une grande police variable, il peut être préférable de diffuser d'abord les variantes de police essentielles, puis de télécharger les autres variantes ultérieurement.

Les polices variables sont désormais compatibles avec tous les navigateurs modernes. Pour en savoir plus, consultez Présentation des polices variables sur le Web.

Sélectionner le bon format

Chaque déclaration @font-face fournit le nom de la famille de polices, qui sert de groupe logique de plusieurs déclarations, de propriétés de police telles que le style, l'épaisseur et l'étirement, ainsi que le descripteur src, qui spécifie une liste hiérarchisée des emplacements de la ressource de police.

@font-face {
  font-family: 'Awesome Font';
  font-style: normal;
  font-weight: 400;
  src: local('Awesome Font'),
       url('/fonts/awesome.woff2') format('woff2'),
       /* Only serve WOFF if necessary. Otherwise,
          WOFF 2.0 is fine by itself. */
       url('/fonts/awesome.woff') format('woff');
}

@font-face {
  font-family: 'Awesome Font';
  font-style: italic;
  font-weight: 400;
  src: local('Awesome Font Italic'),
       url('/fonts/awesome-i.woff2') format('woff2'),
       url('/fonts/awesome-i.woff') format('woff');
}

Notez d'abord que les exemples ci-dessus définissent une seule famille de polices Awesome Font avec deux styles (normal et italique), chacun pointant vers un ensemble différent de ressources de police. À son tour, chaque descripteur src contient une liste de variantes de ressources triées par ordre de priorité, séparées par une virgule:

  • La directive local() vous permet de référencer, de charger et d'utiliser des polices installées en local. Si la police est déjà installée sur le système de l'utilisateur, le réseau est entièrement contourné, ce qui est la méthode la plus rapide.
  • La directive url() vous permet de charger des polices externes et peut contenir un indice format() facultatif indiquant le format de la police référencée par l'URL fournie.

Lorsque le navigateur détermine que la police est nécessaire, il itère la liste de ressources fournie dans l'ordre spécifié et tente de charger la ressource appropriée. Par exemple, en suivant l'exemple ci-dessus:

  1. Le navigateur effectue la mise en page et détermine les variantes de police requises pour afficher le texte spécifié sur la page. Les polices qui ne font pas partie du modèle d'objet CSS (CSSOM) de la page ne sont pas téléchargées par le navigateur, car elles ne sont pas obligatoires.
  2. Pour chaque police requise, le navigateur vérifie si elle est disponible localement.
  3. Si la police n'est pas disponible localement, le navigateur itère sur les définitions externes :
    • Si une indication de format est présente, le navigateur vérifie s'il la prend en charge avant de lancer le téléchargement. Si le navigateur n'est pas compatible avec l'indice, il passe au suivant.
    • Si aucune indication de format n'est fournie, le navigateur télécharge la ressource.

La combinaison de directives locales et externes avec des indications de format appropriées vous permet de spécifier tous les formats de police disponibles et de laisser le navigateur gérer le reste. Le navigateur détermine les ressources requises et sélectionne le format optimal.

Sous-paramètre de la plage Unicode

En plus des propriétés de police telles que le style, l'épaisseur et l'étirement, la règle @font-face vous permet de définir un ensemble de points de code Unicode compatibles avec chaque ressource. Vous pouvez ainsi diviser une grande police Unicode en sous-ensembles plus petits (par exemple, des sous-ensembles latin, cyrillique et grec) et ne télécharger que les glyphes nécessaires pour afficher le texte sur une page donnée.

Le descripteur unicode-range vous permet de spécifier une liste de valeurs de plage séparées par une virgule, chacune pouvant prendre l'une des trois formes suivantes:

  • Un seul point de code (par exemple, U+416)
  • Plage d'intervalle (par exemple, U+400-4ff): indique les codepoints de début et de fin d'une plage
  • Plage de caractères génériques (par exemple, U+4??): les caractères ? indiquent n'importe quel chiffre hexadécimal.

Par exemple, vous pouvez diviser votre famille de polices Awesome en sous-ensembles latin et japonais, que le navigateur télécharge selon les besoins:

@font-face {
  font-family: 'Awesome Font';
  font-style: normal;
  font-weight: 400;
  src: local('Awesome Font'),
       url('/fonts/awesome-l.woff2') format('woff2');
  /* Latin glyphs */
  unicode-range: U+000-5FF;
}

@font-face {
  font-family: 'Awesome Font';
  font-style: normal;
  font-weight: 400;
  src: local('Awesome Font'),
       url('/fonts/awesome-jp.woff2') format('woff2');
  /* Japanese glyphs */
  unicode-range: U+3000-9FFF, U+ff??;
}

L'utilisation de sous-ensembles de plage Unicode et de fichiers distincts pour chaque variante stylistique de la police vous permet de définir une famille de polices composite dont le téléchargement est à la fois plus rapide et plus efficace. Les visiteurs ne téléchargent que les variantes et les sous-ensembles dont ils ont besoin, et ne sont pas obligés de télécharger des sous-ensembles qu'ils ne verront peut-être jamais ou n'utiliseront jamais sur la page.

Presque tous les navigateurs sont compatibles avec unicode-range. Pour assurer la compatibilité avec les navigateurs plus anciens, vous devrez peut-être utiliser le "sous-paramètre manuel". Dans ce cas, vous devez fournir une seule ressource de police contenant tous les sous-ensembles nécessaires et masquer le reste du navigateur. Par exemple, si la page n'utilise que des caractères latins, vous pouvez supprimer les autres glyphes et diffuser ce sous-ensemble particulier en tant que ressource autonome.

  1. Déterminez les sous-ensembles nécessaires:
    • Si le navigateur prend en charge le sous-ensemble de la plage Unicode, il sélectionnera automatiquement le sous-ensemble approprié. La page doit simplement fournir les fichiers de sous-ensemble et spécifier les plages Unicode appropriées dans les règles @font-face.
    • Si le navigateur n'est pas compatible avec le sous-ensemble de la plage Unicode, la page doit masquer tous les sous-ensembles inutiles. Autrement dit, le développeur doit spécifier les sous-ensembles requis.
  2. Générer des sous-ensembles de polices:
    • Utilisez l'outil pyftsubset Open Source pour sous-échantillonner et optimiser vos polices.
    • Certains serveurs de polices, comme Google Fonts, créent automatiquement des sous-ensembles par défaut.
    • Certains services de polices permettent de définir manuellement des sous-ensembles via des paramètres de requête personnalisés, que vous pouvez utiliser pour spécifier manuellement le sous-ensemble requis pour votre page. Consultez la documentation de votre fournisseur de polices.

Sélection et synthèse de polices

Chaque famille de polices peut être composée de plusieurs variantes stylistiques (normal, gras, italique) et de plusieurs épaisseurs pour chaque style. Chacune d'entre elles peut contenir des glyphes de formes très différentes (par exemple, un espacement, une taille ou une forme différents).

Épaisseurs de police

Le diagramme ci-dessus illustre une famille de polices qui propose trois épaisseurs d'italique différentes:

  • 400 (standard)
  • 700 (en gras).
  • 900 (très gras).

Toutes les autres variantes intermédiaires (indiquées en gris) sont automatiquement mappées sur la variante la plus proche par le navigateur.

Lorsqu'un poids pour lequel aucun visage n'existe est spécifié, un visage avec un poids proche est utilisé. En général, les épaisseurs en gras correspondent aux polices plus épaisses, et les épaisseurs légères correspondent aux polices plus fines.

Algorithme de mise en correspondance des polices CSS

La même logique s'applique aux variantes en italique. Le concepteur de polices contrôle les variantes qu'il produira, et vous contrôlez les variantes que vous utiliserez sur la page. Étant donné que chaque variante est un téléchargement distinct, il est conseillé de limiter leur nombre. Par exemple, vous pouvez définir deux variantes en gras pour la famille Awesome Font:

@font-face {
  font-family: 'Awesome Font';
  font-style: normal;
  font-weight: 400;
  src: local('Awesome Font'),
       url('/fonts/awesome-l.woff2') format('woff2');
  /* Latin glyphs */
  unicode-range: U+000-5FF;
}

@font-face {
  font-family: 'Awesome Font';
  font-style: normal;
  font-weight: 700;
  src: local('Awesome Font'),
       url('/fonts/awesome-l-700.woff2') format('woff2');
  /* Latin glyphs */
  unicode-range: U+000-5FF;
}

L'exemple ci-dessus déclare la famille de polices Awesome Font, composée de deux ressources couvrant le même ensemble de glyphes latins (U+000-5FF), mais proposant deux "épaisseurs" différentes : normal (400) et gras (700). Toutefois, que se passe-t-il si l'une de vos règles CSS spécifie un autre poids de police ou définit la propriété font-style sur italic ?

  • Si aucune police ne correspond exactement, le navigateur remplace la police par la plus proche.
  • Si aucune correspondance stylistique n'est trouvée (par exemple, aucune variante en italique n'a été déclarée dans l'exemple ci-dessus), le navigateur synthétise sa propre variante de police.
Synthèse de polices

L'exemple ci-dessus illustre la différence entre les résultats de la police réelle et de la police synthétisée pour Open Sans. Toutes les variantes synthétisées sont générées à partir d'une seule police de poids 400. Comme vous pouvez le constater, il existe une différence notable entre les résultats. Les détails sur la génération des variantes en gras et en italique ne sont pas spécifiés. Par conséquent, les résultats varient d'un navigateur à l'autre et dépendent fortement de la police.

Checklist d'optimisation de la taille de police sur le Web

  • Effectuez un audit et surveillez votre utilisation des polices:n'utilisez pas trop de polices sur vos pages et, pour chaque police, réduisez le nombre de variantes utilisées. Cela permet de proposer une expérience plus cohérente et plus rapide à vos utilisateurs.
  • Évitez les anciens formats dans la mesure du possible:les formats EOT, TTF et WOFF sont plus volumineux que WOFF 2.0. Les formats EOT et TTF sont strictement inutiles, tandis que le format WOFF peut être acceptable si vous devez prendre en charge Internet Explorer 11. Si vous ne ciblez que les navigateurs modernes, l'utilisation de WOFF 2.0 uniquement est l'option la plus simple et la plus performante.
  • Sous-ensemble de vos ressources de police:de nombreuses polices peuvent être sous-ensembles ou divisées en plusieurs plages Unicode afin de n'afficher que les glyphes dont une page particulière a besoin. Cela réduit la taille du fichier et améliore la vitesse de téléchargement de la ressource. Toutefois, lorsque vous définissez les sous-ensembles, veillez à optimiser pour la réutilisation des polices. Par exemple, ne téléchargez pas un ensemble de caractères différent, mais qui se chevauche, sur chaque page. Il est recommandé de créer des sous-ensembles en fonction du script: par exemple, latin et cyrillique.
  • Priorisez local() dans votre liste src:en listant local('Font Name') en premier dans votre liste src, vous vous assurez que les requêtes HTTP ne sont pas effectuées pour les polices déjà installées.
  • Utilisez Lighthouse pour tester la compression du texte.

Effets sur le Largest Contentful Paint (LCP) et le Cumulative Layout Shift (CLS)

En fonction du contenu de votre page, les nœuds de texte peuvent être considérés comme des candidats pour le Largest Contentful Paint (LCP). Il est donc essentiel de vous assurer que vos polices Web sont aussi petites que possible en suivant les conseils de cet article afin que vos utilisateurs voient le texte de votre page le plus rapidement possible.

Si vous craignez que, malgré vos efforts d'optimisation, le texte de la page ne s'affiche pas assez rapidement en raison d'une ressource de police Web volumineuse, la propriété font-display propose plusieurs paramètres qui peuvent vous aider à éviter le texte invisible pendant le téléchargement d'une police. Toutefois, l'utilisation de la valeur swap peut entraîner des décalages de mise en page importants qui affectent le CLS (Cumulative Layout Shift) de votre site. Si possible, envisagez d'utiliser les valeurs optional ou fallback.

Si vos polices Web sont essentielles à votre branding (et par extension, à l'expérience utilisateur), envisagez de les précharger afin que le navigateur ait une longueur d'avance sur leur demande. Cela peut réduire à la fois la période d'échange si vous utilisez font-display: swap ou la période de blocage si vous n'utilisez pas font-display.