Réduire la taille de police sur le Web

La typographie est essentielle pour une bonne conception, l'image de marque, la lisibilité et l'accessibilité. Les polices Web permettent tout cela et plus encore : le texte est sélectionnable, consultable, zoomable et compatible avec les écrans à haute résolution. Il offre un rendu cohérent et net, quelle que soit la taille et la résolution de l'écran. Les polices Web sont essentielles pour 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 globale de performances. Chaque police est une ressource supplémentaire, et certaines polices peuvent bloquer le rendu du texte. Toutefois, ce n'est pas parce qu'une page utilise des polices Web qu'elle doit être plus lente. Au contraire, des polices optimisées, combiné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 un ensemble 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 chemins vectoriels de chaque glyphe et le nombre de glyphes dans une police donnée. Par exemple, Open Sans, l'une des polices Web les plus populaires, contient 897 glyphes, dont des caractères latins, grecs et cyrilliques.

Table des glyphes de la 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 offre un aspect et une expérience cohérents à vos utilisateurs. Par exemple, la famille de polices Noto de Google vise à prendre en charge toutes les langues du monde. Toutefois, notez que la taille totale de Noto, avec toutes les langues incluses, entraîne un téléchargement ZIP de plus de 1, 1 Go.

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

Formats de police Web

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

WOFF et WOFF 2.0 sont largement compatibles et sont pris en charge par tous les navigateurs récents.

  • Proposez la variante WOFF 2.0 aux navigateurs récents.
  • Si cela est absolument nécessaire (par exemple, si vous devez toujours prendre en charge Internet Explorer 11), utilisez WOFF comme solution de remplacement.
  • Vous pouvez également choisir de ne pas utiliser de polices Web pour les navigateurs anciens et de revenir aux polices 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 toutes les bases pour les navigateurs récents 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 plus longs pour les polices Web.

Polices Web et compression

WOFF et WOFF 2.0 disposent d'une compression intégrée. La compression interne de WOFF 2.0 utilise Brotli et offre une compression jusqu'à 30% supérieure à celle de WOFF. Pour en savoir plus, consultez le rapport d'évaluation de WOFF 2.0.

Enfin, il convient de noter que certains formats de police 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, ce qui 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 navigateur.

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

La règle CSS at-rule @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. Vous pouvez utiliser une combinaison de déclarations @font-face pour créer une "famille de polices", que le navigateur utilisera pour évaluer les ressources de police à télécharger et à appliquer à la page actuelle.

Envisager une police variable

Les polices variables peuvent réduire considérablement la taille des fichiers de vos polices lorsque vous avez besoin de plusieurs variantes d'une police. Au lieu de devoir charger les styles normal et gras, ainsi que leurs versions italiques, vous pouvez charger un seul fichier contenant toutes les informations. Toutefois, la taille des fichiers de police variable sera supérieure à celle d'une variante de police individuelle, mais inférieure à la combinaison de nombreuses variantes. Plutôt qu'une grande police variable, il peut être préférable de proposer 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 récents. Pour en savoir plus, consultez Introduction aux polices variables sur le Web.

Sélectionner le bon format

Chaque @font-face déclaration fournit le nom de la famille de polices, qui sert de groupe logique de plusieurs déclarations, les propriétés de police telles que le style, l'épaisseur et l'étirement, ainsi que le descripteur src, qui spécifie une liste priorisée d'emplacements pour 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');
}

Tout d'abord, notez que les exemples ci-dessus définissent une seule famille 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 priorisée de variantes de ressources séparées par une virgule :

  • La directive local() vous permet de référencer, de charger et d'utiliser des polices installées localement. Si l'utilisateur a déjà installé la police sur son système, cela contourne complètement le réseau et est le 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 parcourt 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 nécessaires pour afficher le texte spécifié sur la page. Les polices qui ne font pas partie du modèle objet CSS (CSSOM) de la page ne sont pas téléchargées par le navigateur, car elles ne sont pas requises.
  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 parcourt les définitions externes :
    • Si un indice de format est présent, le navigateur vérifie s'il est compatible avec l'indice avant de lancer le téléchargement. Si le navigateur n'est pas compatible avec l'indice, il passe au suivant.
    • Si aucun indice de format n'est présent, le navigateur télécharge la ressource.

La combinaison de directives locales et externes avec des indices de format appropriés 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-ensemble de plages 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. Cela vous permet de diviser une grande police Unicode en sous-ensembles plus petits (par exemple, les sous-ensembles latin, cyrillique et grec) et de ne télécharger que les glyphes nécessaires pour afficher le texte sur une page particulière.

Le descripteur unicode-range vous permet de spécifier une liste de valeurs de plage délimitées par des virgules, chacune pouvant être sous l'une des trois formes différentes suivantes :

  • Point de code unique (par exemple, U+416)
  • Plage d'intervalle (par exemple, U+400-4ff) : indique les points de code 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 Awesome Font en sous-ensembles latin et japonais, que le navigateur télécharge en fonction des 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 plages Unicode et de fichiers distincts pour chaque variante stylistique de la police vous permet de définir une famille de polices composite à la fois plus rapide et plus efficace à télécharger. 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 ni 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 revenir au "sous-ensemble manuel". Dans ce cas, vous devez fournir une seule ressource de police contenant tous les sous-ensembles nécessaires et masquer le reste au navigateur. Par exemple, si la page n'utilise que des caractères latins, vous pouvez supprimer d'autres glyphes et proposer ce sous-ensemble particulier comme ressource autonome.

  1. Déterminez les sous-ensembles nécessaires :
    • Si le navigateur est compatible avec le sous-ensemble de plages Unicode, il sélectionne automatiquement le bon sous-ensemble. La page n'a qu'à 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 plages 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érez des sous-ensembles de polices :
    • Utilisez l'outil Open Source pyftsubset pour créer des sous-ensembles et optimiser vos polices.
    • Certains serveurs de polices, tels que Google Font, créent automatiquement des sous-ensembles par défaut.
    • Certains services de police autorisent le sous-ensemble manuel 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'elles peut contenir des formes de glyphes très différentes (par exemple, un espacement, une taille ou une forme complètement différents).

Image représentant la lettre A avec des épaisseurs de police croissantes.

Le schéma ci-dessus illustre une famille de polices qui propose trois épaisseurs différentes :

  • 400 (normal).
  • 700 (gras).
  • 900 (très gras).

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

Lorsqu'une épaisseur est spécifiée pour laquelle aucun visage n'existe, un visage avec une épaisseur proche est utilisé. En général, les épaisseurs grasses sont mappées sur des visages plus épais et les épaisseurs légères sur des visages plus légers.

Algorithme de correspondance des polices CSS

La même logique s'applique aux variantes italiques. Le concepteur de polices contrôle les variantes qu'il produit, et vous contrôlez celles que vous utiliserez sur la page. Étant donné que chaque variante est un téléchargement distinct, il est judicieux de limiter le nombre de variantes. Par exemple, vous pouvez définir deux variantes grasses 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 Awesome Font composée de deux ressources qui couvrent le même ensemble de glyphes latins (U+000-5FF), mais proposent deux "épaisseurs" différentes : normale (400) et grasse (700). Toutefois, que se passe-t-il si l'une de vos règles CSS spécifie une épaisseur de police différente ou définit la propriété font-style sur italic ?

  • Si aucune correspondance exacte n'est disponible, le navigateur remplace la police par la correspondance la plus proche.
  • Si aucune correspondance stylistique n'est trouvée (par exemple, aucune variante italique n'a été déclarée dans l'exemple ci-dessus), le navigateur synthétise sa propre variante de police.
Synthèse de police illustrant une déclaration "lorem ipsum" avec des épaisseurs allant de 300 à 800 et des entrées en italique alternées.

L'exemple ci-dessus illustre la différence entre les résultats de police réels et synthétisés pour Open Sans. Toutes les variantes synthétisées sont générées à partir d'une seule police d'épaisseur 400. Comme vous pouvez le voir, il existe une différence notable dans les résultats. Les détails sur la génération des variantes grasses et obliques 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.

Check-list d'optimisation de la taille des polices Web

  • Auditez et surveillez l'utilisation de vos polices : n'utilisez pas trop de polices sur vos pages et, pour chaque police, réduisez le nombre de variantes utilisées. Cela permet d'offrir une expérience plus cohérente et plus rapide à vos utilisateurs.
  • Évitez les formats hérités si possible : les formats EOT, TTF et WOFF sont plus volumineux que WOFF 2.0. Les formats EOT et TTF sont strictement inutiles, tandis que WOFF peut être acceptable si vous devez prendre en charge Internet Explorer 11. Si vous ne ciblez que les navigateurs récents, l'utilisation de WOFF 2.0 uniquement est l'option la plus simple et la plus performante.
  • Créez des sous-ensembles de vos ressources de police : de nombreuses polices peuvent être divisées en plusieurs plages Unicode pour ne fournir que les glyphes requis par une page particulière. 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 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.
  • Donnez la priorité à 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 Largest Contentful Paint (LCP) et 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 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 dès que possible.

Si vous craignez que, malgré vos efforts d'optimisation, le texte de la page ne s'affiche trop lentement en raison d'une ressource de police Web volumineuse, la propriété font-display comporte un certain nombre de 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 changements de mise en page importants qui affectent le Cumulative Layout Shift (CLS) de votre site. Si possible, envisagez d'utiliser les valeurs optional ou fallback.

Si vos polices Web sont essentielles à votre image de marque et, par extension, à l'expérience utilisateur, envisagez de précharger vos polices afin que le navigateur puisse les demander plus rapidement. 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.