J’ai récemment refondu l’interface graphique de notre site de mode, Flip-Zone. Outre la modernisation de la maquette et la simplification de l’ergonomie, un des buts était d’améliorer la réactivité du site : vitesse de chargement, vitesse d’affichage et vitesse des effets interactifs.
Un bon nombre de ces optimisations consiste en une amélioration « normale » du code HTML/Javascript du site (réduire le nombre d’images, de fichiers, de fichiers dynamiques...). En revanche, d’autres éléments sont plus difficiles à détecter, et j’ai donc utilisé l’extension PageSpeed fournie par Google pour Firefox.
Cette extension analyse la structure des fichiers fournis par votre site, et les interactions avec votre serveur, et vous donne une « note » globale, assortie de détails sur les différents points que vous pouvez améliorer. C’est un outil absolument épatant pour optimiser le site Web (une fois qu’on a déjà, autant que possible, optimisé son HTML « normal »).
Après optimisation, la nouvelle version de Flip-Zone atteint (avec la version 1.8 de PageSpeed), le score très honorable de 92, voire 94, sur 100, et obtient le petit « check vert » validant l’optimisation des pages. À titre de comparaison, le présent billet sur Paris-Beyrouth atteint 81/100 et un symbole rouge d’alerte ; rezo.net atteint 83/100 (alerte rouge) ; la page d’accueil de Libération plafonne à 79/100 ; celle du Monde (pourtant très récente) obtient un terrible 68/100.
Et la page d’accueil de l’extension PageSpeed sur le site de Google obtient... 83/100. Avec 92 ou 94/100, Flip-Zone bénéficie donc d’une optimisation très largement au-dessus de la moyenne.
Attaquons différents points, fournis par PageSpeed, sur lesquels je suis intervenu. Notez bien : je vous présente mon expérience personnelle, afin de vous donner des pistes. D’autres méthodes sont certainement possibles, voire préférables. N’hésitez pas à livrer votre propre expérience et vos conseils dans le forum ci-dessous.
Parallelize downloads across hostnames
J’ai déjà traité la question de la parallélisation des chargements dans un précédent billet.
Avec un filtre relativement simple, je répartis les différents appels aux images sur quatre sous-domaines qui, en réalité, pointent vers le même dossier du serveur, ce qui permet aux navigateurs de lancer plus de 2 chargements d’images en même temps.
La simplicité du code et l’économie de moyens nécessaires pour réaliser cela constituent un des points forts de SPIP.
Serve resources from a consistent URL
Le code précédent, fourni pour la parallélisation, est conçu pour que chaque fichier d’image soit toujours situé sur le même sous-nom de domaine. Si vous voyez apparaître cette alerte de PageSpeed, il est probable que vous n’ayez pas activé le passage par le filtre de parallélisation correctement (pas activé sur certains squelettes, pas activé dans certains include
...).
Serve static content from a cookieless domain
PageSpeed suggère alors de « servir » les images (en fait, tous les contenus « statiques ») depuis un domaine « sans cookies ». Je dois avouer que j’ai eu beaucoup de mal à comprendre où était le problème : les fichiers statiques que sont les images étant tous passés sur des sous-noms de domaine de mon domaine principal, je les retrouvais pourtant tous signalés par PageSpeed comme utilisant un cookie.
L’explication de Google est franchement cryptique, alors que la solution est très simple. Le problème ne vient pas d’un réglage au niveau du serveur (et des sous-noms de domaine), contrairement à ce que suggère le terme « cookieless domain ».
C’est Google Analytics, sur mon site, qui posait des cookies « trop larges ». J’utilise l’ancien code (ga.js
), qui pose un cookie qui vise à la fois le domaine principal et ses sous-noms de domaine. De ce fait, le script d’Analytics visait « flip-zone.com », mais aussi « img1.flip-zone.com » (et les autres), alors que ces sous-noms ne servent que des contenus statiques.
Il semble que le nouveau code d’Analytics n’ait plus ce défaut, mais si vous utilisez ga.js
, la solution consiste à ajouter, dans l’appel à Analytics, le code suivant (en indiquant évidemment votre propre domaine principal :
Passer dans les préférences de Firefox, virer les cookies qui correspondaient à ce domaine, et recharger. Le problème est alors « résolu » pour PageSpeed.
Leverage browser caching
Ce point concerne l’indication d’une durée de cache local du côté du client. SPIP insère cette indication lui-même dans les pages qu’il génère via les squelettes, mais il reste tous les autres types de fichiers : images, fichiers CSS et fichiers Javascript. Et ce sont bien pour ces types de fichiers que PageSpeed dénonce l’absence d’indication de cache (le fait que SPIP indique tous les headers nécessaires pour les pages HTML est déjà très appréciable).
J’ai donc modifié ma configuration d’Apache pour qu’il effectue ces opérations lui-même automatiquement. J’ai activé les modules headers
et expire
, en forçant l’activation de l’envoi d’une durée d’expiration longue sur les différents types de fichiers suivants :
Note. La plupart des caches sont ici fixés à une semaine. C’est le minimum recommandé par PageSpeed pour ces types de fichiers. Comme les fichiers Javascript, CSS et images passent par un traitement SPIP, ça ne devrait pas poser de difficulté en cas de modification du site, les noms des fichiers résultants changeant avec la date de création de chaque fichier.
Même si ça n’est pas l’idéal, il est parfois possible d’insérer cette configuration dans .htaccess
, pour les hébergements mutualisés qui ont activé les modules d’Apache mais sans la configuration nécessaire. Je viens par exemple de le faire sur le serveur (mutualisé) qui héberge le présent site.
Après redémarrage du serveur, le problème de cache est résolu pour PageSpeed.
Combine external JavaScript, Combine external CSS
PageSpeed suggère de ne pas appeler plusieurs fichiers Javascript, mais de les regrouper en un seul fichier. Même chose pour les fichiers CSS.
Sur ce point, SPIP offre une fonction absolument épatante : il combine lui-même automatiquement les fichiers Javascript et les fichiers CSS. Il suffit d’activer ces fonctions dans l’espace privé de SPIP : Configuration > Fonctions avancées > Compactage des scripts et CSS.
Voilà un problème de PageSpeed résolu d’un clic dans SPIP !
Enable compression, Specify a Vary : Accept-Encoding header
Tous les navigateurs récents permettent d’échanger des fichiers compactés avec le serveur plutôt que les fichiers texte d’origine. C’est un aspect très important pour accélérer les transferts (surtout que les fichiers texte, tels que HTML, Javascript et CSS, gagnent énormément à être compactés).
Deux méthodes sont possibles.
• Les automatismes de SPIP
SPIP livre en standard tous les outils pour réaliser la compression, avec par ailleurs une mise en cache des fichiers compressés.
Rendez-vous dans la page > Configuration > Fonctions avancées et en bas de page trouvez le pavé « Optimisations et compression ». Activez la compression pour les 3 éléments.
La compression des pages HTML est alors automatiquement gérée par SPIP. (Une bonne chose de faite.)
Le seul point difficile est, maintenant, de parvenir à servir les versions compressées des fichiers CSS et Javascript. Il faut intervenir sur la configuration d’Apache, mais ici cela peut se faire directement dans le fichier .htaccess.
Les fonctions de regroupement des fichiers CSS et Javascript, ainsi que la compression des pages Web par SPIP, stockent en cache deux versions des fichiers : le fichier non compressé, et le même fichier compressé, dont le nom est complété par la terminaison .gz
. Ainsi, dans /local/cache-css
, vous trouvez des couples de fichiers :
Même chose dans /local/cache-js
.
Il faut donc indiquer à Apache de servir, lorsque le navigateur le permet, l’un ou l’autre de ces fichiers. J’insère le code suivant dans .htacces
:
(Le début de ce code, qui définit des AddType
, est assez douteux. Mais il semble fonctionner, et lorsque je le supprime, je rencontre des dysfonctionnements. Code bizarre, donc, mais qui semble bien fonctionner.)
Le problème est résolu pour PageSpeed, avec une solution « pur SPIP ». Cette solution a l’avantage de ne pas demander des droits énormes sur le serveur : si vous avez le droit d’utiliser le fichier .htaccess
de votre serveur Web, vous pouvez certainement l’utiliser.
• La solution mod deflate
L’autre méthode consiste à demander au serveur Apache de prendre en charge la compression de tous les fichiers à la volée. Il faut activer, sur le serveur, le module deflate
, avec la configuration :
(la configuration par défaut ne prend pas en compte les CSS).
Redémarrer Apache, et le problème est résolu pour PageSpeed.
Minify CSS
PageSpeed suggère de réduire la taille des fichiers CSS. On écrit en effet la plupart du temps les fichiers CSS avec de nombreux retours à la ligne et des indentations, de façon à avoir un code très lisible (et donc facile à modifier). Mais ces indentations et ces retours-chariot ont un poids, et PageSpeed suggère de les supprimer.
Si vous activez le regroupement de fichiers CSS dans SPIP, cette fonction fabrique un fichier CSS avec la notation allégée.
Ma difficulté est que, sur Flip-Zone, je n’utilise qu’un seul et unique fichier CSS. Du coup, la fonction de compactage de SPIP ne passe pas dessus (la fonction s’active lorsqu’il y a plusieurs appels de fichiers CSS visant le même support).
Pour les fichiers CSS « faits à la main », il faut transformer la notation développée du type :
par la notation très compacte :
Pour ma part, j’utilise systématiquement le plugin CSS imbriqués pour coder mes CSS, et ce plugin générait un code doté de retours-chariot et d’indentations. J’ai donc récemment modifié ce plugin pour qu’il génère désormais un code « minifié ». Si vous utilisez une version du plugin qui ne le fait pas encore, mettez le à jour.
À noter : les différents fichiers Javascript et CSS étant regroupés, sur chaque page du site, dans des « gros » fichiers, il convient de prendre soin à systématiquement appeler les mêmes fichiers dans chaque type de squelette. Pas de CSS appelés uniquement dans les rubriques et d’autres CSS uniquement dans les articles ; pas de fichiers Javascript uniquement pour les rubriques et d’autres pour les articles. En ayant bien les mêmes appels de CSS et de fichiers Javascript pour les différents types de squelettes, quand on navigue dans le site, on est certain de toujours recharger le même fichier CSS unique et le même fichier Javascript unique. (Cela n’est valable, évidemment, que parce qu’on regroupe automatiquement les différents fichiers externes.)
Remove unused CSS
Le fait d’avoir un gros CSS regroupant les CSS pour tous les squelettes du site peut provoquer l’alerte « Remove unused CSS » dans PageSpeed. Je l’ai vu passer, mais en naviguant un peu dans le site, il semble que PageSpeed ait compris que ces règles CSS étaient tout de même utilisées dans le site, et l’alerte a disparu.
Minify HTML
De la même façon, PageSpeed suggère de « minifier » le code HTML.
Il est notoire que SPIP a tendance à générer un code HTML avec de nombreuses lignes vides, à cause de la succession de boucles. On peut évidemment écrire ses boucles pour limiter cet aspect, mais je trouve que le code source devient alors peu lisible ; je préfère donc conserver mon code source qui génère beaucoup de lignes vides, et intervenir ailleurs.
La première solution consiste à activer le validateur XHTML intégré à SPIP (SAX, qui succède à une première implémentation basée sur tidy). Si vous ne connaissez pas cet outil, vous devriez vous y intéresser : c’est un outil vraiment épatant lors du développement de votre site.
Il s’active en indiquant, simplement,
ou :
Vous obtenez alors un bouton « XML » supplémentaire en haut de vos pages publiques, qui vous permet de « débugger » votre code HTML.
Lorsque votre page est considérée comme suffisamment valide, cette fonctionnalité transforme votre code HTML et le livre sous forme « nettoyée » et structurée : retours chariot bien placés et indentation parfaite.
PageSpeed apprécie assez largement ce nouveau code source reformaté selon la norme XML.
Mais cela ne suffit pas à PageSpeed, qui réclame encore la disparition des retours chariot surnuméraires et, surtout, des indentations.
Plutôt que de « patcher » SAX, je préfère recourir à une seconde méthode. Une fois mon HTML débuggué, je désactive SAX, et je fabrique (dans mes_fonctions.php
un petit filtre en PHP :
Cette fonction supprime les multiples lignes vides et toutes les indentations en début de ligne. Pour la déclencher, j’insère dans mes squelettes la mention :
Ce raccourci #FILTRE
est déjà expliqué dans mon billet sur la mise en parallèle des téléchargements de fichiers externes. Puisque j’ai déjà mis en place un filtre pour la parallélisation, mes squelettes contiennent donc désormais les mentions :
Notez bien : il faut désactiver SAX (ne pas activer la variable $xhtml
), qui passe après ces filtres, et réintroduirait alors les indentations.
Encore des points gagnés sous PageSpeed avec une économie de moyens remarquable.
Les images
Sur Flip-Zone, quasiment toutes mes images passent par les filtres graphiques de SPIP. De ce fait, tous les commentaires concernant les images dans PageSpeed sont « automatiquement » respectés : indiquer la taille des images, pas de redimensionnement d’images directement dans le HTML, compression correcte des fichiers...
Sur tous ces points, je n’ai pas du tout eu besoin d’intervenir pour satisfaire PageSpeed (en revanche, j’ai effectué une optimisation de mon côté pour, plus « normalement », limiter le nombre d’images différentes et leur taille autant que nécessaire).
Specify a character set early
Si vous suivez la même logique que les squelettes standards de SPIP, vous avez bien pensé à indiquer :
en début de vos entêtes. Ce qui fait plaisir à PageSpeed.
Pourquoi je n’obtiens pas 100/100
Sur Flip-Zone, j’obtiens donc 92 ou 94/100. Il me reste deux alertes, que je ne souhaite pas corriger pour l’instant.
• Use efficient CSS
J’ai là des déclarations de CSS considérées comme « très inefficaces » par PageSpeed. Problème qui est accentué par le fait que j’utilise le plugin « CSS imbriqués », qui fabrique automatiquent des déclarations CSS à rallonge.
Je pourrais donc réécrire mes feuilles de style, mais je préfère conserver mes sources CSS structurées et très lisibles, qui me permettent de facilement intervenir sur le code du site.
• Combine external JavaScript
J’ai déjà regroupé, sur mon site, les fichiers Javascript externes que je gère moi-même (les nombreuses extensions jQuery). Mais je suis ici bloqué par la présence des publicités, principalement les pubs AdSense, qui provoquent chacune l’appel de quatre fichiers Javascript différents.
Je ne vois pas de moyen de réellement optimiser cet aspect. C’est un point qui m’échappe totalement sur mon site, puisque je dépends là des fichiers fournis par Google.
En restant raisonnable dans les modifications du code, j’obtiens par exemple 97/100 sur Web Design News ; avant l’intervention, je plafonnais à 80/100. À noter que la désactivation pure et simple des Google Ads n’en améliore pas le score.
Qu’est-ce que ça apporte ?
Au niveau de l’expérience de l’utilisateur, c’est clair : le site est beaucoup plus rapide et donne une bien meilleure impression de fluidité que dans sa version précédente. La visite est, à mon avis, beaucoup plus agréable.
Est-ce que cela va augmenter mon nombre de pages vues (les visiteurs restant plus longtemps sur un site qui va « plus vite ») ? Est-ce que cela va augmenter le nombre de visites (les visiteurs recommandant plus facilement un site plus agréable à consulter) ? Il est trop tôt pour le dire, et il sera difficile de savoir si une augmentation ne serait pas plus liée au changement de graphisme et d’ergonomie. Pour l’instant, honnêtement, je n’ai pas le sentiment que les chiffres soient très différents. Si Google communique beaucoup sur la vitesse absolue des sites Web, je ne suis pas certain que les utilisateurs, eux, soient très sensibles à la différence de vitesse entre un site « qui va plutôt vite » et un site « qui va très vite » (surtout sur Flip-Zone, site qui ne demande pas de beaucoup naviguer entre les pages, mais bien plus de rester longtemps sur une même page présentant une collection de mode complète).
Est-ce que cela va améliorer mon référencement dans Google ? Google a récemment annoncé qu’ils allaient prendre en compte la vitesse dans le score des sites. Mais de manière très limitée, et rien n’indique que, pour Google, il y ait une grosse différence entre un score 84 dans PageSpeed et un score 94 (car implémenter PageSpeed au niveau du robot de Google me semble carrément overkill).
Est-ce que cela va réduire la charge sur mon serveur ? Côté trafic, certainement : les fichiers envoyés vers le visiteur sont moins nombreux, plus petits et offrent une meilleure gestion du cache. Comme je lance beaucoup moins de services HTTP en même temps, j’ai aussi certainement une réduction de la puissance machine utilisée. Mais cet aspect est beaucoup plus lié à l’amélioration de mes squelettes lors de la refonte.
Pour l’instant, ma conclusion est plutôt une question de respect de l’utilisateur : il s’agit de lui proposer une navigation plus fluide et plus agréable. Qu’il y soit sensible au point que cela change son comportement sur le site est très douteux. Quant à la charge du serveur, c’est largement la refonte des squelettes qui joue, bien plus que l’optimisation spécifique pour satisfaire PageSpeed.