La typographie est fondamentale pour une bonne conception, une image de marque, une lisibilité et une accessibilité. Les polices Web permettent tout ce qui précède et bien d'autres: le texte est sélectionnable, disponible dans les recherches, avec zoom, et compatible avec un DPI élevé, ce qui 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 conception, une expérience utilisateur et des performances de qualité.
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 l'affichage du texte, mais 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 à améliorer les temps d'affichage de la page.
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 chemins vectoriels de chaque glyphe et le nombre de glyphes dans une police particulière. Par exemple, Open Sans, qui est l’une des polices Web les plus populaires, contient 897 glyphes, notamment des caractères latins, grecs et cyrilliques.
![Tableau des glyphes de police](https://web.dev/static/articles/reduce-webfont-size/image/font-glyph-table-e2e433419090f.png?authuser=5&hl=fr)
Lors du choix d'une police, il est important de tenir compte des jeux de caractères pris en charge. Si vous devez localiser le contenu de votre page dans plusieurs langues, vous devez utiliser une police capable d'offrir une apparence et une expérience cohérentes à 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, toutes langues comprises, génère un téléchargement ZIP de plus de 1,1 Go.
Dans ce post, vous allez découvrir comment réduire la taille du fichier envoyé pour vos polices Web.
Formats de police Web
Aujourd'hui, deux formats de conteneurs de polices sont recommandés sur le Web:
WOFF et WOFF 2.0 bénéficient d'une large compatibilité et sont compatibles avec tous les navigateurs récents.
- Diffusion de la variante WOFF 2.0 sur les navigateurs récents.
- Si absolument nécessaire (par exemple, si vous devez toujours prendre en charge Internet Explorer 11, par exemple), servez-vous du WOFF en remplacement.
- Vous pouvez également envisager de ne pas utiliser les polices Web pour les anciens navigateurs et de revenir aux polices système. Cette option peut également s'avérer plus performante pour les appareils plus anciens et plus limités.
- WOFF et WOFF 2.0 couvrant toutes les bases des navigateurs récents et anciens encore utilisés, l'utilisation de EOT et TTF n'est plus nécessaire et peut entraîner des temps de téléchargement des polices Web plus longs.
Polices Web et compression
WOFF et WOFF 2.0 ont tous deux une compression intégrée. La compression interne de WOFF 2.0 utilise Brotli et offre une compression jusqu'à 30% supérieure à WOFF. Pour en savoir plus, consultez le rapport d'évaluation WOFF 2.0.
Enfin, il convient de noter que certains formats de police contiennent des métadonnées supplémentaires, telles que des informations d'indice de police et de crénage qui ne sont pas forcément 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 chaque navigateur.
Définir une famille de polices avec @font-face
L'attribut ligne 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 police à télécharger et à appliquer à la page actuelle.
Utiliser une police variable
Les polices variables permettent de réduire considérablement la taille de vos polices si vous avez besoin de plusieurs variantes d'une police. Au lieu de devoir charger les styles standard et gras ainsi que leurs versions en italique, vous pouvez charger un seul fichier contenant toutes les informations. Cependant, les fichiers de police variables seront plus grands qu'une variante de police individuelle, bien qu'ils soient plus petits que la combinaison de nombreuses variantes. Plutôt qu'une seule grande police variable, il peut être préférable de diffuser les variantes de police critiques en premier, puis de télécharger les autres par la suite.
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 format approprié
Chaque déclaration @font-face
fournit le nom de la famille de polices, qui agit comme un groupe logique de plusieurs déclarations, des 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 classées par ordre de priorité et 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, cette méthode contourne complètement le réseau et est la plus rapide. - L'instruction
url()
vous permet de charger des polices externes et peut contenir un indiceformat()
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:
- 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 CSSOM (CSS Object Model) de la page ne sont pas téléchargées par le navigateur, car elles ne sont pas obligatoires.
- Pour chaque police requise, le navigateur vérifie si elle est disponible localement.
- Si la police n'est pas disponible localement, le navigateur effectue une itération sur les définitions externes:
- Si un indicateur de format est présent, le navigateur vérifie s'il est compatible avant de lancer le téléchargement. Si le navigateur n'est pas compatible avec cette suggestion, il passe à la suivante.
- Si aucun indicateur de format n'est présent, le navigateur télécharge la ressource.
La combinaison d'instructions locales et externes avec les 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 quelles ressources sont 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 grande police Unicode 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 d'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 pouvant 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??
):?
correspond à un chiffre hexadécimal.
Par exemple, vous pouvez diviser votre famille Awesome Font en latin et en japonais. sous-ensembles 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 plages Unicode et de fichiers séparés pour chaque variante stylistique de la police vous permet de définir une famille de polices composites à télécharger plus rapidement et plus efficacement. 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 sont susceptibles de ne jamais voir ou d'utiliser 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 opter pour 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 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 en tant que ressource autonome.
- Déterminez les sous-ensembles nécessaires:
- Si le navigateur prend en charge les sous-paramètres de plage Unicode, il sélectionne 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 les sous-paramètres de plage Unicode, tous les sous-ensembles inutiles doivent être masqués sur la page. c'est-à-dire que le développeur doit spécifier les sous-ensembles requis.
- Si le navigateur prend en charge les sous-paramètres de plage Unicode, il sélectionne 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
- Générer 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 Fonts, effectuent automatiquement des sous-ensembles par défaut.
- Certains services de polices 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 d'épaisseurs multiples pour chaque style. Chacun d’eux, à son tour, peut contenir des formes de glyphes très différentes (par exemple, un espacement, une taille ou une forme complètement différentes).
![Épaisseurs de police](https://web.dev/static/articles/reduce-webfont-size/image/font-weights-8351234231fb6.png?authuser=5&hl=fr)
Le diagramme ci-dessus illustre une famille de polices qui propose trois épaisseurs de caractères gras différentes:
- 400 (standard).
- 700 (gras).
- 900 (extra-gras).
Toutes les autres variantes comprises entre les variantes (indiquées en gris) sont automatiquement mappées sur la variante la plus proche par le navigateur.
Lorsqu'un poids est spécifié pour lequel aucun visage n'existe, un visage avec un poids proche est utilisé. En général, les poids en gras correspondent aux visages avec des poids plus lourds et les poids légers à ceux dont les poids sont plus légers.
Algorithme de correspondance des polices CSS
La même logique s'applique aux variantes italique. L'outil de création de polices détermine les variantes qu'ils produisent, et vous déterminez celles que vous utiliserez sur la page. Étant donné que chaque variante correspond à un téléchargement distinct, nous vous conseillons 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;
}
Dans l'exemple ci-dessus, la famille Awesome Font 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 : normale (400) et gras (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 de police n'est disponible, le navigateur utilise 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 de polices](https://web.dev/static/articles/reduce-webfont-size/image/font-synthesis-e57f6dd14d503.png?authuser=5&hl=fr)
L'exemple ci-dessus illustre la différence entre les résultats de police réelle et synthétisé pour Open Sans. Toutes les variantes synthétisées sont générées à partir d'une seule police de 400 épaisseurs. Comme vous pouvez le voir, il existe une différence notable dans les résultats. Les détails concernant la génération des variantes en gras 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.
Liste de contrôle pour l'optimisation de la taille de police Web
- Contrôlez et contrôlez 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. Vous offrirez ainsi à vos utilisateurs une expérience plus cohérente et plus rapide.
- Évitez si possible les anciens formats:les formats EOT, TTF et WOFF sont plus importants que WOFF 2.0. EOT et TTF sont des formats strictement inutiles. 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.
- Définissez des sous-ensembles de vos ressources de police:de nombreuses polices peuvent être sous-ensembles ou divisées en plusieurs plages Unicode afin d'afficher uniquement les glyphes requis par une page spécifique. Cela permet de réduire la taille du fichier et d'améliorer 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 jeu de caractères différent sur chaque page, mais qui se chevauche. A une bonne pratique consiste à effectuer des sous-ensembles en fonction du script: latin et cyrillique, par exemple.
- Donnez la priorité à
local()
dans votre listesrc
:en plaçantlocal('Font Name')
en premier dans la listesrc
, vous vous assurez qu'aucune requête HTTP n'est adressée aux polices déjà installées. - Utilisez Lighthouse pour tester la compression de texte.
Effets sur le LCP (Largest Contentful Paint) 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 LCP (Largest Contentful Paint). Il est donc essentiel de vous assurer que vos polices Web sont aussi petites que possible. Pour ce faire, suivez les conseils fournis dans 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 pas trop longtemps 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 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 qui affectent le CLS (Cumulative Layout Shift) de votre site. Envisagez d'utiliser les valeurs optional
ou fallback
si possible.
Si vos polices Web sont essentielles pour votre branding et, par extension, pour l'expérience utilisateur, pensez à précharger vos polices afin que le navigateur prenne une longueur d'avance sur les demandes. Cela peut réduire à la fois la période d'échange si vous utilisez font-display: swap
et la période de blocage si vous n'utilisez pas font-display
.