Réduire la taille de police sur le Web

La typographie est fondamentale pour une bonne conception, une bonne image de marque, une bonne lisibilité et une bonne accessibilité. Les polices Web permettent, entre autres, de profiter de toutes ces fonctionnalités: le texte peut être sélectionné, recherché, zoomé et adapté au PPP élevé, offrant un rendu cohérent et net du texte, quelles que soient la taille et la résolution de l'écran. Les polices Web sont essentielles à une bonne conception, une bonne expérience utilisateur et de bonnes performances.

L'optimisation des polices Web constitue un élément essentiel de la stratégie globale des performances. Chaque police est une ressource supplémentaire, et certaines polices peuvent bloquer l'affichage du texte. Cependant, ce n'est pas parce que la page utilise WebFonts qu'elle doit s'afficher plus lentement. Au contraire, des polices optimisées, associées à une stratégie judicieuse de chargement et d'application sur la page, peuvent aider à réduire la taille totale de la page et à réduire les délais d'affichage.

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 particulière. 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 police

Lors du choix d'une police d'écriture, il est important de prendre en compte les jeux de caractères acceptés. Si vous devez localiser le contenu de votre page dans plusieurs langues, vous devez utiliser une police d'écriture qui offre un aspect et une expérience cohérents à vos utilisateurs. Par exemple, la famille de polices Noto de Google est compatible avec toutes les langues du monde. Notez toutefois que la taille totale de Noto, avec toutes les langues incluses, génère un téléchargement ZIP d'au moins 1,1 Go.

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

Formats de police Web

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

WOFF et WOFF 2.0 bénéficient d'une compatibilité étendue et sont compatibles avec tous les navigateurs récents.

  • Diffusion de la variante WOFF 2.0 sur les navigateurs récents.
  • En cas d'absolue nécessité, par exemple si vous devez toujours prendre en charge Internet Explorer 11, diffusez le WOFF en remplacement.
  • Sinon, envisagez de ne pas utiliser de polices Web pour les anciens navigateurs et de revenir aux polices système. Cela peut également être plus performant sur les appareils plus anciens et plus limités.
  • WOFF et WOFF 2.0 couvrent toutes les bases pour les navigateurs modernes et anciens. Par conséquent, il n'est plus nécessaire de recourir à l'EOT et au TTF, ce qui peut augmenter le temps de téléchargement des polices Web.

Polices Web et compression

WOFF et WOFF 2.0 disposent tous deux 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 du 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'indice de police et le crénage qui ne sont peut-être pas 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 diffuse automatiquement la variante optimale pour chaque plate-forme et navigateur.

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

La règle arobase du 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 déterminer quelles ressources de police doivent être téléchargées et appliquées à la page actuelle.

Envisagez d'utiliser une police variable

Les polices variables peuvent réduire considérablement la taille de fichier de vos polices lorsque vous avez besoin de plusieurs variantes d'une police. Au lieu d'avoir à charger les styles normal et gras ainsi que leurs versions en italique, vous pouvez charger un seul fichier contenant toutes les informations. Toutefois, les tailles de fichiers de police variables seront plus importantes qu'une variante de police individuelle, bien que plus petite que la combinaison de nombreuses variantes. Plutôt que d'utiliser une grande police variable, il peut être préférable de commencer par diffuser les variantes de police critiques, puis de télécharger les autres plus tard.

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

Sélectionnez le bon format

Chaque déclaration @font-face fournit le nom de la famille de polices, qui agit comme un groupe logique de plusieurs déclarations, les propriétés de police telles que le style, l'épaisseur et l'étirement, et le descripteur src, qui spécifie une liste prioritaire 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 italic), chacun pointant vers un ensemble différent de ressources de police. Chaque descripteur src contient à son tour une liste de variantes de ressources séparées par une virgule et classées par ordre de priorité:

  • La directive local() vous permet de référencer, de charger et d'utiliser des polices installées localement. Si la police est déjà installée sur le système de l'utilisateur, cette méthode contourne complètement le réseau et constitue la méthode la plus rapide.
  • La directive url() vous permet de charger des polices externes. Elles sont autorisées à 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 requises pour afficher le texte spécifié sur la page. Les polices qui ne font pas partie du CSS Object Model (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 parcourt les définitions externes :
    • Si une optimisation 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 ne prend pas en charge l'indice, il passe à la suivante.
    • Si aucun indice de format n'est présent, le navigateur télécharge la ressource.

En associant des instructions locales et externes à des optimisations de format appropriées, vous pouvez spécifier tous les formats de police disponibles et laisser le navigateur s'occuper du reste. Le navigateur détermine les ressources requises et sélectionne le format optimal.

Sous-paramètre de 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. Cela vous permet de diviser une police Unicode volumineuse en sous-ensembles plus petits (par exemple, des sous-ensembles latins, cyrilliques et grecs) et de ne télécharger que les glyphes requis pour afficher le texte sur une page spécifique.

Le descripteur unicode-range vous permet de spécifier une liste de valeurs de plage séparées par une virgule. Chacune d'elles peut se présenter sous l'une des trois formes suivantes:

  • Point de code unique (par exemple, U+416)
  • Plage d'intervalles (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 Japan, chacun téléchargé par le navigateur au besoin:

@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 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. Ils ne sont pas obligés de télécharger des sous-ensembles qu'ils ne verront peut-être jamais ou qu'ils n'utiliseront peut-être jamais sur la page.

Presque tous les navigateurs sont compatibles avec unicode-range. Pour assurer la compatibilité avec des navigateurs plus anciens, vous devrez peut-être revenir au "sous-paramètre manuel". Dans ce cas, vous devez utiliser une seule ressource de police contenant tous les sous-ensembles nécessaires et masquer le reste dans le 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-paramètre de plage Unicode, il sélectionne automatiquement le sous-ensemble approprié. La page doit simplement fournir les fichiers du 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-paramètre de 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 Open Source pyftsubset pour créer des sous-ensembles de polices et les optimiser.
    • Certains serveurs de polices, tels que Google Font, sont automatiquement sous-ensembles par défaut.
    • Certains services de police autorisent la définition manuelle de 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 des polices

Chaque famille de polices peut être composée de plusieurs variantes stylistiques (standard, gras, italique) et de plusieurs épaisseurs pour chaque style. Chacun d'entre eux, à son tour, peut contenir des formes de glyphes très différentes (par exemple, des espaces, des tailles ou une forme complètement différentes).

Épaisseurs de police

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

  • 400 (normal).
  • 700 (gras).
  • 900 (extra gras).

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

Lorsqu'un poids est spécifié alors qu'aucun visage n'existe, un visage d'un poids proche est utilisé. En général, les épaisseurs les plus lourdes correspondent aux visages ayant des épaisseurs plus lourdes et celles dont la pondération est plus légère.

Algorithme de mise en correspondance des polices CSS

La même logique s'applique aux variantes italique. Le concepteur de polices contrôle les variantes qu'il génère, et vous déterminez celles que vous utiliserez sur la page. Étant donné que chaque variante correspond à un téléchargement distinct, nous vous recommandons de limiter le nombre de variantes. 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 Awesome Font. Elle est composée de deux ressources qui couvrent le même ensemble de glyphes latins (U+000-5FF), mais offrent deux "pondérations" différentes : normal (400) et gras (700). Toutefois, que se passe-t-il si l'une de vos règles CSS spécifie une autre épaisseur de police ou définit la propriété font-style sur italic ?

  • Si aucune correspondance de police exacte n'est disponible, le navigateur remplace la correspondance 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 des polices

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'une épaisseur de 400. Comme vous pouvez le voir, il existe une différence notable dans les résultats. La procédure à suivre pour générer les variantes en gras et oblique n'est pas spécifiée. Les résultats varient donc d'un navigateur à l'autre et dépendent fortement de la police utilisée.

Checklist d'optimisation de la taille de police Web

  • Contrôlez et surveillez l'utilisation des polices:n'utilisez pas trop de polices sur vos pages et réduisez le nombre de variantes utilisées pour chaque police. Cela permet d'offrir à vos utilisateurs une expérience plus cohérente et plus rapide.
  • Évitez si possible les anciens formats:les formats EOT, TTF et WOFF sont supérieurs à WOFF 2.0. Les formats EOT et TTF sont strictement inutiles, tandis que WOFF peut être accepté si vous devez utiliser 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.
  • Regroupez les ressources de police en sous-ensembles:de nombreuses polices peuvent être regroupées en sous-ensembles ou en plusieurs plages Unicode afin de fournir uniquement les glyphes requis par une page spécifique. Cela réduit la taille du fichier et améliore la vitesse de téléchargement de la ressource. Toutefois, lorsque vous définissez des sous-ensembles, veillez à optimiser la réutilisation des polices. Par exemple, ne téléchargez pas un jeu de caractères différent, mais qui se chevauche sur chaque page. Une bonne pratique consiste à créer un sous-ensemble basé sur le script (par exemple, latin et cyrillique).
  • Donnez la priorité à local() dans la liste src:indiquez local('Font Name') en premier dans la liste src afin d'éviter que des requêtes HTTP ne soient envoyées pour des polices déjà installées.
  • Utilisez Lighthouse pour tester la compression du texte.

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

En fonction du contenu de votre page, les nœuds de texte peuvent être considérés comme des candidats au Largest Contentful Paint (LCP). Il est donc primordial de vous assurer que la taille de vos polices Web est la plus petite possible. Pour cela, suivez les conseils fournis dans cet article afin que les 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 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 permettant d'éviter le texte invisible lors du téléchargement d'une police. Toutefois, l'utilisation de la valeur swap peut entraîner des décalages de mise en page importants, et avoir une incidence sur la métrique CLS (Cumulative Layout Shift) de votre site. Si possible, utilisez les valeurs optional ou fallback.

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