En plus d'éliminer les téléchargements de ressources inutiles, la meilleure chose à faire pour améliorer la vitesse de chargement des pages est de réduire la taille globale du téléchargement en optimisant et en comprimant les ressources restantes.
Compression des données 101
Une fois que vous avez configuré votre site Web pour éviter de télécharger des ressources inutilisées, l'étape suivante consiste à compresser les ressources restantes éligibles que le navigateur doit télécharger. En fonction du type de ressource (texte, images, polices, etc.), vous avez le choix entre de nombreuses techniques: outils génériques pouvant être activés sur le serveur Web, optimisations de prétraitement pour des types de contenu spécifiques et optimisations spécifiques aux ressources qui nécessitent l'intervention du développeur.
Pour obtenir les meilleures performances, vous devez combiner toutes les techniques suivantes:
- La compression consiste à encoder des informations à l'aide de moins de bits.
- Supprimer les données inutiles est toujours la meilleure solution.
- Il existe de nombreuses techniques et algorithmes de compression différents.
- Vous aurez besoin de différentes techniques pour obtenir la meilleure compression possible.
Le processus de réduction de la taille des données est appelé compression de données. De nombreuses personnes ont contribué à la création d'algorithmes, de techniques et d'optimisations pour améliorer les ratios de compression, la vitesse de compression et la mémoire requise par divers algorithmes de compression.
Une discussion complète sur la compression des données dépasse largement le cadre de ce guide. Toutefois, il est important de comprendre, de manière générale, comment fonctionne la compression et les techniques que vous pouvez utiliser pour réduire la taille des différents composants dont vos pages ont besoin.
Pour illustrer les principes fondamentaux de ces techniques, considérons le processus d'optimisation d'un format de message texte simple inventé uniquement pour cet exemple:
# Below is a secret message, which consists of a set of headers in
# key-value format followed by a newline and the encrypted message.
format: secret-cipher
date: 08/25/16
AAAZZBBBBEEEMMM EEETTTAAA
- Les messages peuvent contenir des annotations arbitraires (parfois appelées commentaires), qui sont indiquées par le préfixe "#". Les annotations n'affectent pas le sens du message ni ses comportements.
- Les messages peuvent contenir des en-têtes, qui sont des paires clé-valeur (séparées par
":"
dans l'exemple précédent) qui apparaissent au début du message. - Les messages contiennent des charges utiles textuelles.
Que pouvez-vous faire pour réduire la taille du message précédent, qui commence à 200 caractères ?
- Le commentaire est intéressant, mais il n'a aucune incidence sur le sens du message. Supprimez-la lors de la transmission du message.
- Il existe de bonnes techniques pour encoder les en-têtes de manière efficace. Par exemple, si vous savez que tous les messages contiennent des éléments "format" et "date", vous pouvez les convertir en ID entiers courts et simplement les envoyer. Toutefois, il se peut que ce ne soit pas le cas. Il est donc préférable de ne pas modifier ce paramètre pour le moment.
- La charge utile est uniquement textuelle. Bien que nous ne sachions pas vraiment quel est son contenu (apparemment, il utilise un
"secret-cipher"
), il suffit de regarder le texte pour constater qu'il contient beaucoup de redondances. Au lieu d'envoyer des lettres répétées, vous pouvez simplement compter le nombre de lettres répétées et les encoder plus efficacement. Par exemple,"AAA"
devient"3A"
, ce qui représente une séquence de trois A.
En combinant ces techniques, vous obtenez le résultat suivant:
format: secret-cipher
date: 08/25/16
3A2Z4B3E3M 3E3T3A
Le nouveau message comporte 56 caractères, ce qui signifie que vous avez compressé le message d'origine de 72%. C'est une réduction significative !
Il s'agit d'un exemple fictif illustrant comment les algorithmes de compression peuvent réduire efficacement la taille de transfert des ressources textuelles. En pratique, les algorithmes de compression sont beaucoup plus sophistiqués que l'exemple précédent. Sur le Web, ils peuvent être utilisés pour réduire considérablement les temps de téléchargement des ressources. En appliquant la compression aux éléments textuels, une page Web peut passer moins de temps à charger des ressources, ce qui permet aux utilisateurs de voir les effets de ces ressources plus tôt qu'ils ne le feraient sans compression.
Minimisation: prétraitement et optimisations spécifiques au contexte
La première technique abordée ici est la minimisation. Bien que la minification ne soit pas strictement un algorithme de compression, elle permet de supprimer les caractères inutiles et redondants utilisés dans le code source afin de rendre les ressources plus lisibles pour les humains. Toutefois, cette lisibilité n'est pas nécessaire pour maintenir la fonctionnalité de ce code source sur les sites Web de production et peut retarder le chargement des ressources sur le Web.
La minimisation est un type d'optimisation spécifique au contenu qui peut réduire considérablement la taille des ressources fournies. Il est préférable d'appliquer ces optimisations dans le cadre de votre processus de compilation et de déploiement. Par exemple, les bundlers sont un type de logiciel couramment utilisé qui peut réduire automatiquement les ressources juste avant le déploiement d'un nouveau code de production sur un site Web.
Le meilleur moyen de compresser les données redondantes ou inutiles est de les supprimer. Toutefois, vous ne pouvez pas supprimer des données arbitraires. Toutefois, dans certains contextes où nous disposons de connaissances spécifiques au contenu du format de données et de ses propriétés, il est possible de réduire considérablement la taille de la charge utile sans affecter sa signification ou ses fonctionnalités réelles.
<html>
<head>
<style>
/* awesome-container is only used on the landing page */
.awesome-container {
font-size: 120%;
}
.awesome-container {
width: 50%;
}
</style>
</head>
<body>
<!-- awesome container content: START -->
<div>
This is my awesome container, and it is <em>so</em> awesome.
</div>
<!-- awesome container content: END -->
<script>
awesomeAnalytics(); // Beacon conversion metrics
</script>
</body>
</html>
Examinez l'extrait HTML précédent et les trois types de contenu qu'il contient:
- Balisage HTML
- CSS pour personnaliser la présentation d'une page
- JavaScript pour alimenter les interactions et d'autres fonctionnalités avancées de la page.
Chacun de ces types de contenu est soumis à des règles différentes concernant ce qui constitue un contenu valide, les commentaires à spécifier, etc. La question qui reste est la suivante : "Comment réduire la taille de cette page ?"
- Les commentaires de code sont les meilleurs amis d'un développeur, mais le navigateur n'en a pas besoin. Supprimer les commentaires CSS (
/* ... */
), HTML (<!-- ... -->
) et JavaScript (// ...
) réduit la taille de transfert totale de la page et de ses sous-ressources. - Un compresseur CSS "intelligent" pourrait remarquer que nous utilisons une méthode inefficace pour définir des règles pour
.awesome-container
et réduire les deux déclarations en une seule sans affecter les autres styles, ce qui permet d'économiser plus d'octets. Sur un grand nombre de règles CSS, la suppression de ce type de redondance peut s'accumuler. Toutefois, il est possible que cette opération ne puisse pas être appliquée de manière agressive, car les sélecteurs sont souvent dupliqués dans différents contextes, par exemple dans les requêtes multimédias. - Les espaces et les tabulations sont des éléments pratiques pour les développeurs en HTML, CSS et JavaScript. Un compresseur supplémentaire pourrait supprimer tous les tabulations et espaces. Contrairement aux autres techniques de déduplication, ce type d'optimisation peut être appliqué de manière assez agressive, à condition que ces espaces ou ces tabulations ne soient pas nécessaires à la présentation de la page. Par exemple, vous devez conserver les espaces dans les passages de texte d'un document HTML, car ils garantissent la lisibilité du contenu que les utilisateurs verront réellement.
<html><head><style>.awesome-container{font-size:120%;width:50%}</style></head><body><div>This is my awesome container, and it is <em>so</em> awesome.</div><script>awesomeAnalytics()</script></body></html>
Après avoir appliqué les étapes précédentes, la page passe de 516 à 204 caractères, ce qui représente une économie d'environ 60%. Certes, ce n'est pas très lisible, mais ce n'est pas nécessaire pour être utilisable. Les pratiques de développement modernes vous permettent également de séparer les versions lisibles et bien formatées de votre code source du code bien optimisé que vous envoyez en production. Combiné aux maquettes sources, qui fournissent une représentation lisible de votre code de production transformé et vous permettent de résoudre plus facilement les bugs en production, vous pouvez bénéficier d'une bonne expérience de développement tout en optimisant les performances pour l'expérience utilisateur.
L'exemple précédent illustre un point important: un compresseur à usage général (par exemple, conçu pour compresser du texte arbitraire) pourrait compresser la page de l'exemple précédent de manière assez efficace, mais il ne saurait jamais supprimer les commentaires, réduire les règles CSS ni effectuer des dizaines d'autres optimisations spécifiques au contenu. C'est pourquoi le prétraitement, la minification et d'autres optimisations contextuelles sont importants.
De même, les techniques décrites ci-dessus peuvent s'étendre au-delà des composants textuels. Les images, les vidéos et les autres types de contenus contiennent tous leurs propres métadonnées et diverses charges utiles. Par exemple, chaque fois que vous prenez une photo avec un appareil photo, son fichier intègre généralement de nombreuses informations supplémentaires: paramètres de l'appareil photo, position, etc. Selon votre application, ces données peuvent être essentielles (par exemple, un site de partage de photos) ou complètement inutiles. Vous devez déterminer s'il est utile de la supprimer. En pratique, ces métadonnées peuvent ajouter jusqu'à plusieurs dizaines de kilo-octets pour chaque image.
En résumé, pour optimiser l'efficacité de vos composants, commencez par dresser un inventaire des différents types de contenus et réfléchissez aux types d'optimisations spécifiques aux contenus que vous pouvez appliquer pour réduire leur taille. Ensuite, une fois que vous avez déterminé de quoi il s'agit, automatisez ces optimisations en les ajoutant aux étapes de compilation et de publication pour vous assurer qu'elles sont appliquées de manière cohérente à chaque nouvelle version en production.
Compression de texte avec des algorithmes de compression
La deuxième étape consiste à appliquer un algorithme de compression aux éléments textuels pour réduire leur taille. Cette approche va plus loin en recherchant de manière agressive des modèles répétables dans les charges utiles textuelles avant de les envoyer à l'utilisateur et de les décompresser une fois qu'elles arrivent dans le navigateur de l'utilisateur. Cela permet de réduire encore et de manière significative ces ressources, et de réduire les temps de téléchargement.
- gzip et Brotli sont des algorithmes de compression couramment utilisés qui fonctionnent le mieux sur les éléments textuels: CSS, JavaScript et HTML.
- Tous les navigateurs modernes sont compatibles avec la compression gzip et Brotli, et annoncent la compatibilité avec les deux dans l'en-tête de requête HTTP
Accept-Encoding
. - Votre serveur doit être configuré pour activer la compression. Par défaut, le logiciel du serveur Web permet souvent aux modules de compresser les ressources textuelles.
- gzip et Brotli peuvent être affinés pour améliorer les ratios de compression en ajustant le niveau de compression. Pour gzip, les paramètres de compression vont de 1 à 9, le meilleur étant 9. Pour Brotli, cette plage est comprise entre 0 et 11, où 11 correspond à la meilleure qualité. Toutefois, les paramètres de compression plus élevés prennent plus de temps. Pour les ressources compressées dynamiquement (c'est-à-dire au moment de la requête), les paramètres au milieu de la plage offrent généralement le meilleur compromis entre le taux de compression et la vitesse. Toutefois, la compression statique est possible, c'est-à-dire que la réponse est compressée à l'avance et peut donc utiliser les paramètres de compression les plus agressifs disponibles pour chaque algorithme de compression.
- Les réseaux de diffusion de contenu (CDN) proposent généralement une compression automatique des ressources éligibles. Les CDN peuvent également gérer la compression dynamique et statique pour vous, ce qui vous permet de vous soucier d'un aspect de compression en moins.
gzip et Brotli sont des compresseurs courants qui peuvent être appliqués à n'importe quel flux d'octets. En interne, ils se souviennent de certains des contenus précédemment examinés d'un fichier, puis tentent de trouver et de remplacer les fragments de données en double de manière efficace.
En pratique, gzip et Brotli fonctionnent mieux avec les contenus textuels, atteignant souvent des taux de compression allant jusqu'à 70 à 90% pour les fichiers plus volumineux. Toutefois, l'exécution de ces éléments d'algorithmes déjà compressés à l'aide d'autres algorithmes (comme la plupart des formats d'image qui utilisent des techniques de compression sans perte ou avec perte) n'entraîne que peu ou pas d'amélioration.
Tous les navigateurs modernes annoncent la prise en charge de gzip et de Brotli dans l'en-tête de requête HTTP Accept-Encoding
. Toutefois, il incombe au fournisseur d'hébergement de s'assurer que le serveur Web est correctement configuré pour diffuser la ressource compressée lorsque le client le demande.
Fichier | Algorithme | Taille non compressée | Taille compressée | Taux de compression |
---|---|---|---|---|
angular-1.8.3.js | Brotli | 1 346 Kio | 256 Kio | 81 % |
angular-1.8.3.js | gzip | 1 346 Kio | 329 Kio | 76% |
angular-1.8.3.min.js | Brotli | 173 Kio | 53 Kio | 69% |
angular-1.8.3.min.js | gzip | 173 Kio | 60 Kio | 65 % |
jquery-3.7.1.js | Brotli | 302 Kio | 69 Kio | 77% |
jquery-3.7.1.js | gzip | 302 Kio | 83 Kio | 73 % |
jquery-3.7.1.min.js | Brotli | 85 Kio | 27 Kio | 68% |
jquery-3.7.1.min.js | gzip | 85 Kio | 30 ko | 65 % |
lodash-4.17.21.js | Brotli | 531 Kio | 73 Kio | 86 % |
lodash-4.17.21.js | gzip | 531 Kio | 94 Kio | 82 % |
lodash-4.17.21.min.js | Brotli | 71 Kio | 23 Kio | 68% |
lodash-4.17.21.min.js | gzip | 71 Kio | 25 Kio | 65 % |
Le tableau précédent indique les économies que la compression Brotli et gzip peut apporter à quelques bibliothèques JavaScript connues. Les économies varient de 65% à 86 %, en fonction du fichier et de l'algorithme. Pour information, le niveau de compression maximal a été appliqué à chaque fichier pour Brotli et gzip. Dans la mesure du possible, préférez Brotli à gzip.
L'activation de la compression est l'une des optimisations les plus simples et les plus efficaces à implémenter. Si votre site Web n'en profite pas, vous manquez une excellente occasion d'améliorer les performances pour vos utilisateurs. Heureusement, de nombreux serveurs Web fournissent des configurations par défaut qui permettent cette optimisation importante. Les CDN, en particulier, sont très efficaces pour l'implémenter de manière à équilibrer la vitesse et le ratio de compression.
Pour voir rapidement la compression en action, ouvrez les outils pour les développeurs Chrome, ouvrez le panneau Network (Réseau), chargez une page de votre choix et observez le bas du panneau Network.
Comme dans l'image précédente, vous devriez voir une répartition des éléments suivants:
- Nombre de requêtes, qui correspond au nombre de ressources chargées pour la page.
- Taille de transfert de toutes les requêtes. Elle reflète l'efficacité de la compression appliquée à l'une des ressources d'une page.
- Taille des ressources de toutes les requêtes. Cette valeur reflète la taille des ressources de la page après leur décompression.
Effets sur les Core Web Vitals
Les améliorations de performances ne peuvent pas être mesurées si des métriques ne les reflètent pas. L'initiative Core Web Vitals vise à créer et à sensibiliser les utilisateurs aux métriques qui reflètent l'expérience utilisateur réelle. Contrairement aux métriques (comme le temps de chargement de la page simple, par exemple) qui ne traduisent pas clairement la qualité de l'expérience utilisateur.
Lorsque vous appliquez les optimisations décrites dans ce guide aux ressources de votre site Web, les effets sur les métriques Core Web Vitals peuvent varier en fonction des ressources optimisées et des métriques concernées. Toutefois, voici quelques cas où l'application de ces optimisations peut améliorer les métriques Core Web Vitals de votre site Web:
- Les ressources HTML minifiées et compressées peuvent améliorer le chargement de ce code HTML, la visibilité de ses sous-ressources et, par conséquent, leur chargement. Cela peut être bénéfique pour le LCP (Largest Contentful Paint) d'une page. Bien que des indices de ressources tels que
rel="preload"
puissent être utilisés pour affecter la visibilité des ressources, en utiliser trop peut entraîner des problèmes de conflit de bande passante. En veillant à ce que la réponse HTML d'une requête de navigation soit compressée, les ressources qu'elle contient peuvent être découvertes dès que possible par le lecteur de préchargement. - Certains candidats à la compression de LCP peuvent également être chargés plus tôt à l'aide de la compression. Par exemple, la durée de chargement des ressources des images SVG candidates au LCP peut être réduite grâce à la compression basée sur le texte. Cela diffère des optimisations que vous pourriez apporter à d'autres types d'images, qui sont intrinsèquement compressés par d'autres méthodes de compression, comme la compression avec pertes des images JPEG.
- De plus, les nœuds de texte peuvent également être des candidats au LCP. La façon dont les techniques décrites dans ce guide fonctionnent dépend de l'utilisation d'une police Web pour le texte de vos pages Web. Si vous utilisez une police Web, les bonnes pratiques d'optimisation des polices Web s'appliquent. Toutefois, si vous n'utilisez pas de polices Web, mais plutôt des polices système qui s'affichent sans entraîner de durée de chargement de ressources, la minimisation et la compression de votre CSS réduisent cette durée, ce qui signifie que le rendu des nœuds de texte LCP potentiels peut avoir lieu plus tôt.
Conclusion
La façon dont vous optimisez l'encodage et le transfert des éléments textuels est un concept de performances de référence, mais qui a un impact important. Assurez-vous de faire tout votre possible pour vous assurer que les ressources éligibles à la minification et à la compression bénéficient de ces optimisations.
Plus important encore, assurez-vous que ces processus sont automatisés. Pour la minification, utilisez un outil de regroupement pour appliquer la minification aux ressources éligibles. Assurez-vous que la configuration de votre serveur Web est compatible avec la compression, mais surtout, utilisez la compression la plus efficace disponible. Pour simplifier la tâche, utilisez des CDN pour automatiser la compression. Ils peuvent non seulement compresser les ressources pour vous, mais aussi le faire très rapidement.
En inscrivant ces concepts de référence en termes de performances dans l'architecture de votre site Web, vous pouvez vous assurer que vos efforts d'optimisation des performances sont sur de bonnes bases et que les optimisations ultérieures peuvent s'appuyer sur une base solide de bonnes pratiques de référence.