Optimiser le chargement et l'affichage de WebFont

Ilya Grigorik
Ilya Grigorik

Une police Web "complète" qui inclut toutes les variantes stylistiques dont vous n'avez pas besoin, ainsi que tous les glyphes (qui peuvent rester inutilisés) peut facilement entraîner un téléchargement de plusieurs mégaoctets. Dans cet article, vous découvrirez comment optimiser le chargement des polices Web pour que les visiteurs ne téléchargent que ce qu'ils utiliseront.

Pour résoudre le problème des fichiers volumineux contenant toutes les variantes, la règle CSS @font-face est spécifiquement conçue pour vous permettre de diviser la famille de polices en un ensemble de ressources. (par exemple, des sous-ensembles Unicode et des variantes de style distinctes).

Compte tenu de ces déclarations, le navigateur détermine les sous-ensembles et les variantes requis, puis télécharge l'ensemble minimal requis pour afficher le texte, ce qui est très pratique. Toutefois, si vous ne faites pas attention, cela peut également créer un goulot d'étranglement des performances dans le chemin critique du rendu et retarder l'affichage du texte.

Le comportement par défaut

Le chargement différé des polices entraîne une implication cachée importante qui peut retarder le rendu du texte. Le navigateur doit construire l'arborescence de rendu, qui dépend des arborescences DOM et CSSOM, avant de savoir quelles ressources de police il a besoin pour afficher le texte. Par conséquent, les requêtes de polices sont bien retardées après d'autres ressources critiques, et le navigateur risque de ne pas pouvoir afficher le texte jusqu'à ce que la ressource soit récupérée.

Chemin critique du rendu de la police

  1. Le navigateur demande le document HTML.
  2. Le navigateur commence à analyser la réponse HTML et à construire le DOM.
  3. Le navigateur détecte les ressources CSS, JS et d'autres, puis distribue les requêtes.
  4. Le navigateur construit le CSSOM une fois que tout le contenu CSS a été reçu et le combine avec l'arborescence DOM pour construire l'arborescence de rendu.
    • Les requêtes de police sont envoyées une fois que l'arborescence de rendu indique les variantes de police nécessaires pour afficher le texte spécifié sur la page.
  5. Le navigateur effectue la mise en page et affiche le contenu à l'écran.
    • Si la police n'est pas encore disponible, il est possible que le navigateur n'affiche aucun pixel de texte.
    • Une fois la police disponible, le navigateur affiche les pixels de texte.

Le "race" entre le premier rendu du contenu de la page, qui peut être effectué peu de temps après la création de l'arborescence de rendu et la demande de ressource de police, est ce qui crée le "problème de texte vide" dans lequel le navigateur peut afficher la mise en page, mais omet tout texte.

En préchargeant WebFonts et en utilisant font-display pour contrôler le comportement des navigateurs avec les polices indisponibles, vous pouvez éviter les pages vides et les décalages de mise en page dus au chargement des polices.

Précharger vos ressources WebFont

S'il est fort probable que votre page ait besoin d'une police Web spécifique hébergée sur une URL que vous connaissez à l'avance, vous pouvez tirer parti de la hiérarchisation des ressources. L'utilisation de <link rel="preload"> déclenche une requête pour la police Web au début du chemin critique du rendu, sans avoir à attendre la création du CSSOM.

Personnaliser le délai d'affichage du texte

Bien que le préchargement augmente la probabilité qu'une police Web soit disponible lors de l'affichage du contenu d'une page, il n'offre aucune garantie. Vous devez toujours tenir compte du comportement des navigateurs lorsqu'ils affichent du texte qui utilise un élément font-family, qui n'est pas encore disponible.

Dans l'article Éviter le texte invisible lors du chargement de la police, vous pouvez constater que le comportement par défaut du navigateur n'est pas cohérent. Toutefois, vous pouvez indiquer aux navigateurs récents comment vous souhaitez qu'ils se comportent à l'aide de font-display.

Navigateurs pris en charge

  • 60
  • 79
  • 58
  • 11.1

Source

À l'instar des comportements de délai d'expiration des polices existants mis en œuvre par certains navigateurs, font-display segmente la durée de vie du téléchargement d'une police en trois périodes principales:

  1. La première période correspond à la période de blocage de police. Pendant cette période, si le style de police n'est pas chargé, tout élément qui tente de l'utiliser doit s'afficher avec un style de police de remplacement invisible. Si la police se charge correctement pendant la période de blocage, elle est utilisée normalement.
  2. La période de remplacement des polices se produit immédiatement après celle du blocage des polices. Pendant cette période, si le style de police n'est pas chargé, tout élément qui tente de l'utiliser doit s'afficher avec un style de police de remplacement. Si la police se charge correctement pendant la période d'échange, elle est utilisée normalement.
  3. La période d'échec de la police se produit immédiatement après la période de remplacement des polices. Si le type de police n'est pas encore chargé au début de cette période, il est marqué comme ayant échoué, ce qui entraînera un remplacement de police normal. Sinon, le type de police est utilisé normalement.

Si vous comprenez ces périodes, vous pouvez utiliser font-display pour déterminer le mode d'affichage de votre police selon qu'elle a été téléchargée ou non.

Pour utiliser la propriété font-display, ajoutez-la à vos règles @font-face:

@font-face {
  font-family: 'Awesome Font';
  font-style: normal;
  font-weight: 400;
  font-display: auto; /* or block, swap, fallback, optional */
  src: local('Awesome Font'),
       url('/fonts/awesome-l.woff2') format('woff2'), /* will be preloaded */
       url('/fonts/awesome-l.woff') format('woff'),
       url('/fonts/awesome-l.ttf') format('truetype'),
       url('/fonts/awesome-l.eot') format('embedded-opentype');
  unicode-range: U+000-5FF; /* Latin glyphs */
}

font-display accepte actuellement la plage de valeurs suivante:

  • auto
  • block
  • swap
  • fallback
  • optional

Pour en savoir plus sur le préchargement des polices et sur la propriété font-display, consultez les articles suivants:

API Font Load

Utilisés conjointement, <link rel="preload"> et le CSS font-display vous offrent un contrôle important sur le chargement et l'affichage des polices, sans augmenter la surcharge. Toutefois, si vous avez besoin de personnalisations supplémentaires et que vous êtes prêt à engendrer les frais généraux liés à l'exécution de JavaScript, il existe une autre option.

L'API Font Load fournit une interface de script permettant de définir et de manipuler des polices CSS, de suivre la progression de leur téléchargement et d'ignorer le comportement de chargement différé par défaut. Par exemple, si vous êtes certain qu'une variante de police particulière est requise, vous pouvez la définir et demander au navigateur de lancer une récupération immédiate de la ressource de police:

Navigateurs pris en charge

  • 35
  • 79
  • 41
  • 10

Source

var font = new FontFace("Awesome Font", "url(/fonts/awesome.woff2)", {
  style: 'normal', unicodeRange: 'U+000-5FF', weight: '400'
});

// don't wait for the render tree, initiate an immediate fetch!
font.load().then(function() {
  // apply the font (which may re-render text and cause a page reflow)
  // after the font has finished downloading
  document.fonts.add(font);
  document.body.style.fontFamily = "Awesome Font, serif";

  // OR... by default the content is hidden,
  // and it's rendered after the font is available
  var content = document.getElementById("content");
  content.style.visibility = "visible";

  // OR... apply your own render strategy here...
});

En outre, comme vous pouvez vérifier l'état de la police (via la méthode check()) et suivre la progression du téléchargement, vous pouvez également définir une stratégie personnalisée pour l'affichage du texte sur vos pages:

  • Vous pouvez maintenir tout le rendu du texte jusqu'à ce que la police soit disponible.
  • Vous pouvez implémenter un délai d'expiration personnalisé pour chaque police.
  • Vous pouvez utiliser la police de remplacement pour débloquer le rendu et injecter un nouveau style qui utilise la police souhaitée une fois qu'elle est disponible.

Mieux encore, vous pouvez combiner les stratégies ci-dessus pour différents contenus de la page. Par exemple, vous pouvez retarder l'affichage du texte sur certaines sections jusqu'à ce que la police soit disponible, utiliser une police de remplacement, puis effectuer un nouveau rendu une fois le téléchargement de la police terminé.

Une mise en cache appropriée est

Les ressources de police sont généralement des ressources statiques qui ne font pas l'objet de mises à jour fréquentes. Par conséquent, elles sont idéales pour un délai d'expiration long. Veillez à spécifier à la fois un en-tête ETag conditionnel et une règle Cache-Control optimale pour toutes les ressources de police.

Si votre application Web utilise un service worker, la diffusion de ressources de police selon une stratégie axée sur le cache est appropriée dans la plupart des cas d'utilisation.

Vous ne devez pas stocker de polices à l'aide de localStorage ou IndexedDB, car chacun d'eux présente son propre ensemble de problèmes de performances. Le cache HTTP du navigateur constitue le mécanisme le plus efficace et le plus robuste pour fournir des ressources de police au navigateur.

Checklist pour le chargement des polices Web

  • Personnalisez le chargement et l'affichage des polices à l'aide de <link rel="preload">, de font-display ou de l'API Font Loading:le comportement de chargement différé par défaut peut retarder l'affichage du texte. Ces fonctionnalités de la plate-forme Web vous permettent d'ignorer ce comportement pour des polices spécifiques, et de spécifier des stratégies d'affichage et de délai avant expiration personnalisées pour différents contenus de la page.
  • Spécifiez une revalidation et des règles de mise en cache optimales:les polices sont des ressources statiques qui sont rarement mises à jour. Assurez-vous que vos serveurs fournissent un horodatage maximal de longue durée et un jeton de revalidation pour permettre la réutilisation efficace des polices entre différentes pages. Si vous utilisez un service worker, une stratégie axée sur le cache est appropriée.

Tests automatisés du comportement de chargement de WebFont avec Lighthouse

Lighthouse peut vous aider à automatiser le processus visant à vous assurer que vous respectez les bonnes pratiques d'optimisation des polices Web.

Les audits suivants peuvent vous aider à vous assurer que vos pages continuent à suivre les bonnes pratiques d'optimisation des polices Web au fil du temps: