Une nouvelle façon de réduire l'impact du chargement des polices : les descripteurs de police CSS

Publié: 2022-03-10
Résumé rapide ↬ Les polices Web sont souvent terribles pour les performances Web et aucune des stratégies de chargement de polices n'est particulièrement efficace pour résoudre ce problème. Les options de police à venir pourraient enfin tenir la promesse de faciliter l'alignement des polices de secours sur les polices finales.

Le chargement des polices a longtemps été un bug des performances Web, et il n'y a vraiment pas de bons choix ici. Si vous souhaitez utiliser des polices Web, vos choix sont essentiellement Flash of Invisible Text (alias FOIT) où le texte est masqué jusqu'au téléchargement de la police ou Flash of Unstyled Text (FOUT) où vous utilisez initialement la police système de secours, puis mettez-la à niveau vers le police Web lors du téléchargement. Aucune des deux options n'a vraiment "gagné" car aucune n'est vraiment satisfaisante, pour être honnête.

font-display n'était-il pas censé résoudre ce problème ?

La propriété font-display pour @font-face donnait ce choix au développeur Web alors qu'auparavant le navigateur le décidait (IE et Edge favorisaient FOUT dans le passé, alors que les autres navigateurs favorisaient FOIT). Cependant, au-delà de cela, cela n'a pas vraiment résolu le problème.

Un certain nombre de sites sont passés à font-display: swap lors de sa première sortie, et Google Fonts en a même fait la valeur par défaut en 2019. L'idée ici était qu'il était préférable pour les performances d' afficher le texte aussi rapidement que possible , même si c'est dans la police de secours, puis pour échanger la police lors du téléchargement final.

J'étais également favorable à cela à l'époque, mais je me trouve de plus en plus frustré par «l'effet d'hydratation» lorsque les téléchargements de polices Web et les caractères se développent (ou se contractent) en raison des différences entre les polices. Smashing Magazine, comme la plupart des éditeurs, utilise des polices Web et la capture d'écran ci-dessous montre la différence entre le rendu initial (avec les polices de secours) et le rendu final (avec les polices Web) :

Deux captures d'écran d'un article de Smashing Magazine avec des polices différentes. Le texte est sensiblement de taille différente et une phrase supplémentaire peut s'intégrer lorsque les polices Web sont utilisées.
Article de Smashing Magazine avec police de secours et polices Web complètes. ( Grand aperçu )

Désormais, mises côte à côte, les polices Web sont considérablement plus agréables et correspondent à la marque Smashing Magazine. Mais nous constatons également qu'il existe une certaine différence dans la disposition du texte avec les deux polices. Les polices sont de tailles très différentes et, à cause de cela, le contenu de l'écran se déplace. En cette ère où les Core Web Vitals et les Cumulative Layout Shifts sont (à juste titre !) reconnus comme préjudiciables aux utilisateurs, font-display: swap est un mauvais choix à cause de cela.

Je suis revenu à font-display: block sur les sites dont je m'occupe car je trouve vraiment le décalage de texte assez choquant et ennuyeux. S'il est vrai que le block n'arrêtera pas les décalages (la police est toujours rendue en texte invisible), cela les rend au moins moins visibles pour l'utilisateur. J'ai également optimisé le chargement des polices en préchargeant les polices que j'ai rendues aussi petites que possible en auto-hébergant des sous-ensembles de polices - de sorte que les visiteurs ne voient souvent les polices de secours que pendant une courte période. Pour moi, la "période de bloc" de swap était trop courte et je préférerais honnêtement attendre un peu plus longtemps pour obtenir le rendu initial correct.

Plus après saut! Continuez à lire ci-dessous ↓

Utilisation font-display: optional possibilité de résoudre FOIT et FOUT en option - à un coût

L'autre option consiste à utiliser font-display: optional . Cette option rend essentiellement les polices Web facultatives, ou pour le dire différemment, si la police n'est pas là au moment où la page en a besoin, il appartient au navigateur de ne jamais l'échanger. Avec cette option, nous évitons à la fois FOIT et FOUT en n'utilisant essentiellement que des polices qui ont déjà été téléchargées.

Si la police Web n'est pas disponible, nous revenons à la police de secours, mais la navigation sur la page suivante (ou un rechargement de cette page) utilisera la police - car elle devrait avoir terminé le téléchargement à ce moment-là. Cependant, si la police Web n'est pas importante pour le site, il peut être judicieux de la supprimer complètement, ce qui est encore mieux pour les performances Web !

Les premières impressions comptent et avoir ce chargement initial sans polices Web semble un peu trop. Je pense aussi - sans aucune preuve pour étayer cela d'ailleurs ! – que cela donnera aux gens l'impression, peut-être inconsciemment, que quelque chose ne va pas sur le site Web et peut avoir un impact sur la façon dont les gens utilisent le site Web.

Ainsi, toutes les options de police ont leurs inconvénients, y compris la possibilité de ne pas utiliser de polices Web du tout ou d'utiliser des polices système (ce qui est limitatif, mais peut-être pas aussi limitatif que beaucoup le pensent !).

Rendre votre police de secours plus proche de votre police

Le Saint Graal du chargement des polices Web a été de rapprocher la police de secours de la police Web réelle afin de réduire autant que possible le décalage notable, de sorte que l'utilisation de l' swap ait moins d'impact. Bien que nous ne puissions jamais éviter complètement les changements, nous pouvons faire mieux que dans la capture d'écran ci-dessus. L'application Font Style Matcher de Monica Dinculescu est souvent citée dans les articles sur le chargement des polices et donne un aperçu fantastique de ce qui devrait être possible ici. Il vous permet utilement de superposer le même texte dans deux polices différentes pour voir à quel point elles sont différentes et d'ajuster les paramètres de police pour les aligner plus étroitement :

Captures d'écran de Font Style Matcher montrant deux ensembles sur du texte superposé l'un sur l'autre, le haut ayant de grandes différences et le bas ayant le texte très similaire.
Captures d'écran de Font Style Matcher avec la valeur par défaut, les mêmes paramètres pour deux polices (en haut) et des paramètres ajustés pour donner une meilleure correspondance (en bas). ( Grand aperçu )

Malheureusement, le problème avec la correspondance du style de police est que nous ne pouvons pas appliquer ces styles CSS uniquement aux polices de secours, nous devons donc utiliser JavaScript et l'API FontFace.load pour appliquer (ou annuler) ces différences de style lorsque le Web la police se charge .

La quantité de code n'est pas énorme, mais cela ressemble toujours à un peu plus d'effort qu'il ne devrait l'être. Bien qu'il existe d'autres avantages et possibilités d'utiliser l'API JavaScript pour cela, comme l'explique Zach Leatherman dans cette conférence fantastique datant de 2019 - vous pouvez réduire les refusions et gérer le mode data-server et prefers-reduced-motion bien que cela (notez cependant que les deux ont depuis été exposés au CSS depuis cette conversation).

Il est également plus délicat de gérer les polices en cache que nous avons déjà, sans parler des différences dans les différents styles de secours. Ici, sur Smashing Magazine, nous essayons un certain nombre de solutions de rechange pour tirer le meilleur parti des polices système installées par différents utilisateurs et systèmes d'exploitation :

 font-family: Mija,-apple-system,Arial,BlinkMacSystemFont,roboto slab,droid serif,segoe ui,Ubuntu,Cantarell,Georgia,serif;

Savoir quelle police est utilisée, ou avoir des réglages séparés pour chacun et s'assurer qu'ils sont appliqués correctement peut rapidement devenir assez complexe.

Une meilleure solution arrive

Donc, c'est un bref rattrapage sur où en sont les choses à ce jour. Cependant, de la fumée commence à apparaître à l'horizon.

Comme je l'ai mentionné plus tôt, le principal problème avec l'application des différences de style de secours était de les ajouter, puis de les supprimer. Et si nous pouvions dire au navigateur que ces différences ne concernent que les polices de secours ?

C'est exactement ce que fait un nouvel ensemble de descripteurs de polices proposé dans le cadre du module CSS Fonts Niveau 5. Ceux-ci sont appliqués aux déclarations @font-face où la police individuelle est définie.

Simon Hearne a écrit à propos de cette proposition de mise à jour de la spécification des descripteurs font-face qui comprend quatre nouveaux descripteurs : ascent-override , descent-override , line-gap-override et advance-override (abandonnés depuis). Vous pouvez jouer avec le terrain de jeu F-mods que Simon a créé pour charger vos polices personnalisées et de secours, puis jouer avec les remplacements pour obtenir une correspondance parfaite.

Comme l'écrit Simon, la combinaison de ces quatre descripteurs nous a permis de remplacer la disposition de la police de secours pour qu'elle corresponde à la police Web, mais ils ne modifient vraiment que l'espacement et le positionnement verticaux. Donc, pour l'espacement des caractères et des lettres, nous devrons fournir du CSS supplémentaire.

Mais les choses semblent encore changer. Plus récemment, advance-override a été abandonné au profit du prochain descripteur size-adjust qui nous permet de réduire les changements de mise en page en faisant correspondre une police de secours et une police Web principale via un facteur d'échelle pour les glyphes (pourcentage).

Comment ça marche? Disons que vous avez le CSS suivant :

 @font-face { font-family: 'Lato'; src: url('/static/fonts/Lato.woff2') format('woff2'); font-weight: 400; } h1 { font-family: Lato, Arial, sans-serif; }

Ensuite, ce que vous feriez est de créer une @font-face pour la police de secours Arial et de lui appliquer des descripteurs d'ajustement . Vous obtiendrez alors l'extrait CSS suivant :

 @font-face { font-family: 'Lato'; src: url('/static/fonts/Lato.woff2') format('woff2'); font-weight: 400; } @font-face { font-family: "Lato-fallback"; size-adjust: 97.38%; ascent-override: 99%; src: local("Arial"); } h1 { font-family: Lato, Lato-fallback, sans-serif; }

Cela signifie que lorsque le Lato-fallback est utilisé initialement (car Arial est une police local et peut être utilisée immédiatement sans aucun téléchargement supplémentaire), les paramètres d' size-adjust et ascent-override vous permettent de vous rapprocher de la police Lato. C'est une déclaration @font-face supplémentaire à écrire, mais certainement beaucoup plus facile que les cerceaux que nous devions franchir auparavant !

Dans l'ensemble, il y a quatre principaux descripteurs @font-face inclus dans cette spécification : size-adjust , ascent-override , descent-override et line-gap-override avec quelques autres encore en cours d'examen pour l'indice, l'exposant et d'autres cas d'utilisation .

Malte Ubl a créé un outil très utile pour calculer automatiquement ces paramètres étant donné deux polices et un navigateur qui prend en charge ces nouveaux paramètres (plus à ce sujet dans un instant !). Comme le souligne Malte, les ordinateurs sont bons pour ce genre de choses ! Idéalement, nous pourrions également exposer ces paramètres pour les polices courantes aux développeurs Web, par exemple, peut-être donner ces conseils dans des collections de polices comme Google Fonts ? Cela aiderait certainement à augmenter l'adoption.

Maintenant, différents systèmes d'exploitation peuvent avoir des paramètres de police légèrement différents et les obtenir exactement correctement est fondamentalement une tâche impossible, mais ce n'est pas le but. L'objectif est de combler l'écart en utilisant font-display: swap n'est plus une expérience aussi choquante, mais nous n'avons pas besoin d'aller aux extrêmes des polices Web optional ou non.

Quand pouvons-nous commencer à l'utiliser ?

Trois de ces paramètres ont déjà été livrés dans Chrome depuis la version 87 , bien que le descripteur size-adjust la clé ne soit pas encore disponible dans un navigateur stable. Cependant, Chrome Canary l'a, tout comme Firefox derrière un drapeau, donc ce n'est pas un concept abstrait et lointain, mais quelque chose qui pourrait atterrir très bientôt.

Pour le moment, la spécification contient toutes sortes de clauses de non-responsabilité et d'avertissements indiquant qu'elle n'est pas encore prête pour le temps réel, mais on a certainement l'impression qu'elle y arrive. Comme toujours, il y a un équilibre entre nous, concepteurs et développeurs, le testant et donnant des commentaires, et décourageant son utilisation, afin que la mise en œuvre ne reste pas bloquée car trop de personnes finissent par utiliser une version antérieure.

Chrome a déclaré son intention de rendre size-adjust disponible dans Chrome 92, dont la sortie est prévue le 20 juillet, indiquant probablement qu'il est presque là.

Donc, pas encore tout à fait prêt, mais il semble que cela arrive dans un avenir très proche. En attendant, jouez avec la démo dans Chrome Canary et voyez si elle peut se rapprocher un peu plus de la résolution de vos problèmes de chargement de polices et de l'impact CLS qu'ils provoquent.