Performance et webfonts d'icônes
Introduction
Les webfonts permettent entre-autres d’inclure des icônes. De nombreuses librairies existent : par exemple GLYPHICONS (en partie fournie avec bootstrap) ou Font Awesome.
Pour fonctionner sous l’ensemble des navigateurs il est commun d’inclure 4 formats : OpenType, WOFF, TrueType et SVG. C’est ce dernier qui nous servira par la suite.
Passer par une webfont pour gérer les icônes a l’avantage de pouvoir modifier leur rendu en CSS (il est par exemple très facile de modifier leur couleur ou leur taille). Celle-ci étant vectorielle, l’icône pourra donc avoir n’importe quelle taille déterminée en CSS. De plus, tout comme cela pourrait être le cas pour des icônes intégrées via une sprite, un seul hit HTTP est utilisé pour charger l’ensemble des icônes.
En plus d’avoir des librairies d’icônes, il est possible d’intégrer ces propres icônes en webfont, à partir de ses propres fichiers SVG (ou des icônes en SVG d’une librairie, comme celle que vient de récemment open-sourcer google : material-design-icons). Le plugin grunt-webfont s’aquitte très bien de cette tâche.
Voici un exemple d’inclusion de webfont :
Une classe va indiquer d’utiliser la font définie plus haut.
Il est ensuite possible d’accéder aux icônes via leur caractère. Autant de sélecteurs que d’icônes seront créés :
Notre icône pourra alors être insérée comme ceci :
Problématiques
Nombre de fichiers inclus
Lorsque vous voulez inclure des icônes provenant de plusieurs librairies (GLYPHICONS, Font Awesome…), il faut inclure plusieurs fichiers (un fichier par librairie).
La même problématique se pose lorsque vous utilisez vos propres icônes, il faudra inclure le fichier généré par webfont, ainsi que la librairie d’icônes.
Nous aurons donc un hit HTTP par source d’icônes (si GLYPHICONS et Font Awesome sont tous deux intégrés, il y aura deux hits).
Poids des librairies
Si seulement quelques icônes vous intéressent dans la librairie, il est dommage de l’inclure totalement.
Voici les tailles des fichiers inclus par Font Awesome :
Selon le navigateur utilisé entre 55Kb et 281Kb seront utilisés, cela pour rendre accessible 479 icônes. Dommage si c’est pour seulement en utiliser une poignée.
Il existe actuellement 1 446 demandes de nouvelles icônes pour Font Awesome. Le problème ne risque pas de s’améliorer avec le temps.
Nombre de sélecteurs CSS générés
Comme vu plus haut, nous allons avoir un sélecteur CSS pour utiliser la font. Rien de gênant dans celui-ci.
Par contre, ensuite nous allons avoir un sélecteur CSS par icône. Si l’on reprend le cas de Font Awesome, cela fait 479 sélecteurs. Si vous devez supporter IE, cela peut être très gênant, celui-ci ayant une limitation de 4095 sélecteurs par feuille de style. Dans les autres cas, ce sera de nombreux sélecteurs parsés inutilement par le navigateur.
Fichiers SVG originaux non disponibles
Les fichiers originaux ayant servis à la création de la font (et notamment des fichiers SVG) ne sont parfois pas disponibles, seulement la webfont. Continuons avec l’exemple de Font Awesome, ceux-ci ne sont pas présent dans le dépot git.
Solution
La réponse : le plugin grunt grunt-webfont-svg-extractor.
Ce plugin va vous permettre d’extraire un fichier SVG par icône se trouvant dans le fichier SVG Webfont. Nous allons ensuite pouvoir utiliser ces SVG (éventuellement tirés de différentes sources) pour en créer une webfont avec le plugin grunt-webfont cité précédement.
Principe
Le plugin va partir d’un fichier CSS et un fichier SVG.
Par exemple ces fichiers pour glyphicon/bootstrap :
- glyphicons-halflings-regular.svg
- bootstrap.css
Un fichier CSS pour des webfont contient des définitions d’icônes comme celles-ci :
Et l’icône est définie comme ceci dans le fichier SVG :
Nous allons donc devoir faire la correspondance entre le caractère unicode du fichier SVG et l’attribut content
défini dans le fichier CSS pour récupérer les noms des SVG exportés.
De plus, le chemin SVG défini dans l’attribut d
n’est pas utilisable directement dans un fichier SVG, quelques transformations sont nécessaires avant d’écrire le fichier.
C’est donc ces deux opérations que va effectuer le plugin grunt-webfont-svg-extractor.
Tutorial
Les instructions qui vont suivre nécessitent d’avoir quelques notions sur l’utilisation de Grunt.
Il faudra tout d’abord installer le plugin grunt-webfont-svg-extractor
.
Puis charger celui-ci dans le fichier Gruntfile.js
.
Puis ensuite configurer la tâche grunt :
A propos de ces options :
- fontPath : chemin vers le fichier SVG
- cssPath : chemin vers le fichier CSS, celui-ci permettra le mapping entre le nom du fichier et le path SVG à utiliser
- outputDir : dossier où seront créées les icônes en SVG (il peut être intéressant d’utiliser grunt-contrib-clean pour vider le dossier au début du lancement de grunt).
- preset : peut valoir soit “glyphicon” ou “fontawesome”
- icons : tableau contenant les noms des icônes à exporter. Si cette option n’est pas définie, tous les icônes seront exportées.
Une autre option est disponible :
- regexp :
/.glyphicon-(.*):before/
: la valeur capturée correspond au nom de l’icône exporté. l’expression rationnelle permet de filtrer les sélecteurs CSS sur lequels rechercher un attribut “content” à faire correspondre avec le fichier SVG.
Nous allons ensuite créer un fichier webfont. Pour cela nous passerons par grunt-webfont
, que nous allons commencer par installer :
Puis charger celui-ci dans le fichier Gruntfile.js
.
En configurant le plugin de cette façon, l’ensemble des fichiers SVG du dossier tmp
seront utilisés pour créer une webfont dans le dossier output
. La classe à utiliser pour indiquer d’utiliser cette font sera icon
et toutes les classes définissant le caractère à utiliser seront préfixées par icon-
(viendra ensuite le nom du fichier SVG sans son extension).
Petit bonus, le fichier exporté par webfont sera nommé en fonction de son contenu. Il sera donc possible de configurer votre serveur web pour mettre en cache ces fichiers pour une très longue durée.
Un exemple complet est disponible dans le dossier example du dépôt de grunt-webfont-svg-extractor
.
Etude d’un cas
Sur le baromètre AFUP nous avions besoin de 3 icônes de Bootstrap et 2 icônes de Font Awesome.
Nous aurions donc dû faire 2 appels HTTP sur des fichiers qui pèseraient en tout entre 78Kb et 344Kb (selon le type de font utilisé par le navigateur). Entre 23Kb et 63Kb pour les GLYPHICONS de Bootstrap et entre 55Kb et 281Kb pour Font Awesome.
De plus 682 sélecteurs se trouveraient dans la CSS (202 pour les GLYPHICONS de Bootstrap et 480 pour Font Awesome).
En utilisant ce plugin nous ne chargeons qu’un seul fichier pesant entre 1,2Kb et 6Kb et avons seulement 6 sélecteurs CSS.
Le gain a donc été d’un hit HTTP, et entre 76.8Kb et 338Kb ainsi que 676 selecteurs CSS.
Licences
En utilisant ce plugin, attention à bien respecter les licences des différentes librairies.