Les dernières actualités d'Alsacreations.com
Selon httparchive.org, la masse des fichiers de polices de caractère pèse en moyenne 100 ko dans une page web, soit bien plus que les poids des fichiers HTML et CSS, et autant qu'une bonne grosse image.
Autre relevé intéressant : de nos jours plus de 69% de sites web proposent de télécharger une police personnalisée. On est bien loin des antiques Arial, Verdana et Times New Roman du bon vieux temps !
Le problème est que selon les navigateurs, un fichier de fonte non chargé peut bloquer ou altérer l'affichage des contenus, ce qui est d'autant plus observable sur des terminaux mobiles.
Le processus d'affichage d'une page web dans le navigateur est tel que la page demeure blanche tant que toutes les ressources HTML, CSS (éventuellement JavaScript) ne sont pas chargées et que l'arbre du document n'est pas entièrement constitué. On parle de ressources "bloquantes".
Nous savons que d'autres types de ressources telles que les images ou vidéos sont embarquées de manière asynchrone - le navigateur les charge progressivement - et n'ont que peu d'impact sur la rapidité d'affichage.
Qu'en est-il des fichiers de polices de caractères ?
La réponse est "ça dépend de ce qu'on appelle bloquant".
Lorsqu'une fonte personnalisée est sollicitée par le navigateur, plusieurs scénarios peuvent se produire en attendant que celle-ci soit intégralement chargée. Parmi les déroulements possibles figurent les deux cas de "FOUT" et de "FOIT".
Le terme "FOUT" signifie Flash Of Unstyled Text, la traduction approximative serait "flash de texte sans style" :
Le terme "FOIT" signifie Flash Of Invisible Text ("flash de texte invisible") :
À première vue, le comportement de FOUT semble le plus cohérent et le moins déstabilisant : qui pourrait souhaiter que les contenus soient invisibles tant que la police n'est pas chargée ?
Figurez-vous que les choses ne sont pas aussi simples qu'elles n'y paraissent. Voici par exemple : l'affichage des pictogrammes issus de polices d'icônes (font-icons), dont la plus célèbre est Font Awesome (utilisée par Bootstrap) :
Pour tenter de gérer au mieux ces disparités entre les types de fontes et leurs usages, chaque navigateur a adopté son comportement propre :
Et les spécifications dans tout ça ? Bah, elles ne se mouillent pas trop. Leur préconisation est très officiellement : "Les agents utilisateurs décident de leur stratégie de chargement de fontes (FOUT ou FOIT) tant que le fichier n’est pas chargé".
En partant de ce constat, tentons d'établir des stratégies pour limiter la casse.
Pas de suspense, oubliez vos vieux TTF et EOT : le meilleur format de police en terme de qualité-prix est WOFF2 (Web Open Font Format 2) compatible avec une majorité de navigateurs de bureau et mobiles aujourd'hui.
Prévoyez toutefois un format alternatif pour les quelques glorieux anciens. Le meilleur choix étant l'itération précédente .woff reconnue par plus de 95% des terminaux.
À titre indicatif, voici un comparatif du poids des différents formats de la police freeware Rocket Fuel :
Votre déclaration @font-face
idéale peut ainsi se résumer à ceci :
@font-face {
font-family: kiwi;
src:
url("kiwi.woff2") format("woff2"),
url("kiwi.woff") format("woff");
}
Elle permettra par la suite d'appliquer la fonte à vos éléments portant une classe spécifique :
.kiwi {
font-family: kiwi, sans-serif;
}
Facile non ?Contrairement à une croyance commune, il n'est pas toujours idéal de tirer profit des fournisseurs de polices tels que Google Fonts ou Typekit. Ces tierces parties ("third parties") qui hébergent les fichiers peuvent provoquer une dépendance et des ralentissements ainsi que d'autres désagréments inhérents à tous ces types de services externes.
Héberger sa fonte sur ses propres serveurs vous permet un contrôle total des fichiers, de leur disponibilité et de leur optimisation. Pour information, Alsacréations partage un projet Github "Webfonts" où il vous est possible de récupérer et héberger plusieurs dizaines de familles de polices optimisées pour le Web.
FontSquirrel Webfont Generator est un outil en ligne gratuit bien connu des intégrateurs qui souhaitent tirer le meilleur de leur polices web.
Après avoir chargé vos fichiers de fonte, et en ayant activé le mode Expert avec tous ses superpouvoirs, vous pourrez tendre vers la perfection en terme de poids de fichier final sans altérer la qualité de votre police.
Parmi les options très intéressantes, retenez principalement :
Lorsque vous aurez fini vos réglages, FontSquirrel vous proposera de télécharger un dossier complet contenant vos différents fichiers de fonte, mais aussi une page HTML de démonstration assortie à sa feuille de style CSS et le code @font-face
qu'il vous suffira d'adapter à votre projet.
À présent que nos fichiers de police sont optimisés dans un format parfait, intéressons-nous aux comportements de FOUT et de FOIT évoqués en début d'article.
Quoi qu'il arrive, nous allons les subir, alors tentons de nous en accommoder au mieux !
Je vous propose trois stratégies différentes, pouvant être cumulées :
Charger les fichiers de police via JavaScript est une façon de forcer le FOUT pour interdire le FOIT, ce que l'on peut considérer à juste titre comme étant "le moins pire des comportements".
Le principe étant de faire croire au navigateur que seule la police alternative doit être affichée, puis dans un second temps de charger et d'afficher la police personnalisée via JavaScript. Les contenus ne seront donc jamais invisibles au chargement.
Cette technique requiert de convertir le fichier de fonte en base64 pour l'utiliser via Data-URI et le stocker dans un fichier CSS. Puis c'est JavaScript qui se missionne de charger notre fichier de "fonte-CSS" de manière asynchrone.
Exemple sommaire de fichier CSS :
@font-face {
font-family: kiwi;
src:
url(data:application/font-woff;
charset=utf-8;base64,d09GRgABAAAAANnkABMAAAABPxgAAQA…)
format("woff");
}
Exemple sommaire de script JavaScript :
<script>
// Déclaration de loadCSS ici...
function loadCSS() { ... }
// Chargement du fichier CSS
loadCSS("data-uri.css");
</script>
<noscript><link href="data-uri.css" rel="stylesheet"></noscript>
Cet exemple tire profit de l'outil LoadCSS proposé librement par l'équipe de FilamentGroup, réputée pour ses compétences en Responsive Webdesign et en performances web.
Si vous souhaitez éviter de recourir à JavaScript pour améliorer l'affichage de vos polices web, une autre stratégie est possible : celle d'accélérer le chargement des fichiers de fonte.
Sachez que W3C a récemment proposé la spécification rel="preload"
dont les bénéfices sont parfaitement expliqués dans cet extrait de l'excellente Documentation de Mozilla :
La valeur preload de l'attribut rel pour l'élément <link> permet d'écrire des requêtes déclaratives de récupération au sein de l'élément <head>. On peut ainsi indiquer les ressources dont la page aura besoin peu après son chargement. Cela permet de les précharger au début du chargement de la page, avant que le rendu intervienne. On s'assure donc que les ressources nécessaires soient disponibles plus tôt, évitant ainsi de bloquer le rendu initial de la page et améliorant les performances.
L'attribut rel=preload
n'est malheureusement pas reconnu par tous les navigateurs actuellement, mais il constitue un extraordinaire bonus pour tous les bons élèves tels que Chrome ou Firefox, et très bientôt leurs successeurs. Pourquoi ne pas faire bénéficier dès aujourd'hui vos visiteurs de ce bonus très simple à mettre en œuvre ?
Le site Shopify ne s'est pas posé la question très longtemps. Sa conclusion est sans appel et consignée dans un article élogieux (en anglais) : "Comment 17 lignes de codes ont accéléré l'affichage de Shopify de 50% ?".
Voici un exemple illustrant comment précharger à l'avance deux fichiers de police :
<link rel="preload" href="fonte-1.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="fonte-2.woff2" as="font" type="font/woff2" crossorigin>
Une autre stratégie consiste à charger conditionnellement les fichiers de police, ou plus exactement de ne pas les solliciter sur un périphérique mobile par exemple pour des raisons de performance.
L'objectif est de proposer par défaut une police système et de lier la police personnalisée à l'aide de CSS Media Queries en se basant sur une taille d'écran par exemple.
Concrètement, c'est très simple à mettre en place. Pour commencer, sachez que la déclaration @font-face
n'impose pas le chargement de la ressource, celle-ci ne sera chargée que lorsqu'elle sera explicitement demandée en l'appliquant sur un élément de la page.
Dans la pratique, il suffit de procéder ainsi pour ne charger et afficher la fonte "kiwi" que lorsque l'écran est supérieur à 576px :
body {
font-family: arial,sans-serif;
}
@media (min-width: 576px) {
body {
font-family: kiwi, arial, sans-serif;
}
}
Cette méthode est très bénéfique en terme de performances mais n'est bien entendu pas idéale car il faut :
À ce propos, sachez que de plus en plus de sites web (Booking, Medium, WordPress, GitHub, Alsacréations, entre autre) ont cessé de tenter d'imposer une police identique à tous leurs visiteurs, même lorsqu'il s'agit d'une police classique : plutôt que de proposer Arial, Verdana ou Times, ils ont opté pour une police variable adaptée à chaque système d'exploitation :
body {
font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;
}
Cette famille de fontes, appelée "System Font Stack" propose à chaque utilisateur sa police habituelle sur son OS : sur Windows ce sera "Segoe UI" ou "Tahoma" pour les plus anciens, sur Android ce sera "Roboto", etc. Ainsi vos visiteurs ne seront pas surpris par vos choix typographiques et se sentiront comme chez eux dans vos pages de contenus.
Le site Booking.com explique son choix (en anglais) : "Implementing system fonts on Booking.com — A lesson learned.".
Dans un avenir plus ou moins proche, différents moyens permettront de ne plus subir les comportements indésirables de FOUT et de FOIT lorsque les polices seront en transit vers nos navigateurs.
Une spécification officielle, la Font Loading API, est prévue dans les bacs, et un émulateur FontFaceObserver est déjà utilisable en production.
La spécification CSS Font Loading Module Level 3 est encore à l'état de brouillon mais n'en demeure pas moins supportée par une très large part des navigateurs récents.
Ce module prévoit une interface de script permettant de gérer très finement les étapes du chargement des fichiers de police et le comportement a adopter pour le navigateur au cas par cas.
var f = new FontFace("newfont", "url(newfont.woff)", {});
f.load().then(function (loadedFace) {
document.fonts.add(loadedFace);
document.body.style.fontFamily = "newfont, serif";
});
document.fonts.ready().then(function() {
// Toutes les familles @font-face sont prêtes
});
FontFaceObserver est un script de "polyfill" réalisé par Bram Stein et permettant d'émuler Font Loading API pour les navigateurs qui ne reconnaissent pas encore la spécification. Sa mise en oeuvre est assez simple.
Partie JavaScript :
// include fontFaceObserver here...
new w.FontFaceObserver( "Source Sans Pro" )
.check()
.then( function(){
w.document.documentElement.className += " fonts-loaded";
});
Partie CSS :
body {
font-family: sans-serif;
}
.fonts-loaded body {
font-family: "Source Sans Pro", sans-serif;
}
Ceci permet un chargement asynchrone du fichier, puis une fois que celui-ci est prêt à être utilisé, l'ajout d'une classe à l'élément racine <html> pour appliquer les propriétés de police sur l'ensemble du document.
Vous connaissez la propriété CSS font-display
? Rassurez-vous, vous n'êtes pas seul·e. En effet, cette nouveauté n'est encore qu'à l'état de proposition non officielle, c'est à dire qu'elle n'a même pas encore atteint le stade de brouillon au W3C.
Toujours est-il que cette propriété a la bonne idée de réaliser exactement notre fantasme, c'est à dire de pouvoir décider quel sera le comportement des navigateurs lors du chargement de nos fontes.
Par exemple, il est possible d'imposer un FOUT c'est à dire d'afficher immédiatement la police alternative avec la valeur swap
:
@font-face {
font-family: kiwi;
src: ...;
font-display: swap;
}
Le support des navigateurs, sans surprise, est quasi nul aujourd'hui : Chrome vient tout juste de l'implémenter et il est probable que d'autres vont suivre. En tout cas, rien ne vous empêche de l'ajouter en bonus, vous ne casserez pas le Web.
Vous trouverez de plus amples informations sur cette fonctionnalité sur le site de Zach Leatherman.
Autre domaine à surveiller de près (merci à ThomasLinard pour son commentaire avisé) : celui des "Variable Fonts".
Sans entrer dans les détails, disons que les variable fonts ont fait leur entrée dans CSS Fonts Module Level 4 et consistent en un format de fonte qui intègre en un seul fichier toutes les graisses et autres variations de familles de police. Ainsi, plutôt que de devoir charger un fichier pour la version classique, un autre pour la version grasse, un autre pour l'italique, etc. tout sera réuni en un seul fichier. C'est bien évidemment une bénédiction pour les performances web.
Je vous invite à lire l'article "What do Variable Fonts mean for Web Developers?" qui explique très bien le point de vue d'un développeur à ce sujet.
Dans le domaine de la performance tout autant que celui de l'esthétique et de l'ergonomie, le choix de vos polices web relève d'une importance cruciale. De leur nombre et de leur poids dépendront la rapidité d'affichage de vos contenus et la qualité d'expérience de vos utilisateurs.
Ne faites pas comme le site de vanityfair.fr qui importait près de 450 ko de fichiers de fontes à une époque. Ne cédez pas à la tentation d'imposer de multiples chargements juste parce que "ces 8 polices sont troooop classes". Faites des choix. Optimisez. Optez pour des stratégies de chargement. Tous vos visiteurs, sans exception, vous en remercieront.