YSlow – comment optimiser son site web en quelques minutes ?
Votre site est poussif ? Le temps de chargement ou d’affichage des pages est trop long ? Avant de penser à changer d’hébergement et avant de se plonger dans le code afin d’y trouver des points d’amélioration, il est peut-être important de regarder de plus près comment sont conçues vos pages web.
Yahoo propose une extension Firefox très intéressante, nommée YSlow. Il faut prononcer « why slow » pour « pourquoi ça rame ? ». 😉 Cette extension permet de faire des contrôles sur une page à partir d’une checklist qui se compose de 13 points :
- Réduire le nombre de requêtes HTTP
- Utiliser un CDN
- Ajouter des entêtes HTTP d’expiration
- Compresser le contenu des données échangées
- Placer les feuilles de style CSS le plus tôt possible
- Placer les scripts Javascript le plus tard possible
- Éviter les expressions CSS
- Extraire un maximum de CSS et Javascript dans des fichiers à part
- Réduire le nombre de résolution DNS
- Réduire la taille du Javascript
- Éviter les redirections HTTP
- Supprimer les scripts en double
- Supprimer les ETags
En respectant ces 13 points, votre site web devrait être plus performant si ce n’était pas le cas auparavant. Le plugin permet de donner une note globale pour une page avec une note pour chaque point. La documentation est très bien faite. Alors plutôt que d’expliquer tous les points en donnant des axes d’amélioration, je vais vous détailler un exemple concret. 🙂
Je travaille sur un site pour les fans du jeu de cartes à collectionner Magic: The Gathering. Le design est plus que rudimentaire (avis aux artistes ! :-D), c’est pourquoi je n’en ai pas encore parlé ici. La base de données des cartes est assez conséquente et regorge d’information. Il se peut donc que certaines pages puissent mettre un peu de temps à s’afficher. C’est pourquoi j’ai travaillé sur l’optimisation du site.
Comme vous pouvez le voir, la première note obtenue était un D avec un score de 61 (sur 100).
J’ai donc décidé de commencer par le dernier point en supprimant les ETags. En effet, cette information est très peu et très mal utilisée. Alors, pour réduire le taille des données transportées autant l’enlever. Et cela se fait très facilement (si vous utilisez Apache comme serveur HTTP) en ajoutant la ligne suivante dans votre fichier .htaccess :
FileETag none
Après avoir fait cette modification, la note globale était toujours un D et le score est seulement monté à 63. Mais pour ce point, le F s’est transformé en B. 🙂
Ensuite, je me suis attaqué au positionnement des entêtes HTTP d’expiration. Ce paramétrage permet de réduire le nombre de requête HTTP faite par le navigateur en lui indiquant de conserver certaines données plus ou moins longtemps. C’est tout aussi simple à mettre en place que l’astuce précédente puisqu’il faut modifier le même fichier en y ajoutant les lignes suivantes :
ExpiresActive On ExpiresByType text/css "access plus 30 days" ExpiresByType text/javascript "access plus 7 days" ExpiresByType application/x-javascript "access plus 7 days" ExpiresByType application/javascript "access plus 7 days" ExpiresByType image/x-icon "access plus 7 days" ExpiresByType image/vnd.microsoft.icon "access plus 7 days" ExpiresByType image/png "access plus 30 days" ExpiresByType image/gif "access plus 30 days" ExpiresByType image/jpeg "access plus 30 days" ExpiresByType image/jpg "access plus 30 days" ExpiresByType application/x-shockwave-flash "access plus 60 days"
Les délais d’expirations dépendent beaucoup de la vie du site. En effet, si des fichiers CSS ou Javascript sont menés à changer régulièrement, il faut réduire ce délai sous peine que les butineurs des visiteurs ne prennent pas en compte la nouvelle version. Cette optimisation a permis d’obtenir un B pour ce point et un C en note globale avec un score de 73. Ça progresse…
Après avoir réglé ces deux points, la compression du contenu m’a parue être une optimisation essentielle et à moins coût. Ceci réduit considérablement la taille des fichiers HTML ou XML et ainsi les pages se téléchargent plus rapidement. Pour activer la compression GZip des données, il faut encore ajouter dans le fichier .htaccess la ligne suivante :
AddOutputFilterByType DEFLATE text/javascript application/javascript text/css application/xhtml+xml text/html text/plain application/json text/xml
Avec la compression GZIP, YSlow attribue la note A pour ce point et la note globale B avec un score qui continue sa progression en arrivant à 82.
En regardant le comportement du butineur, j’ai remarqué que le composant Javascript Script.aculo.us générait un grand nombre de requête HTTP pour télécharger de nombreux fichiers de scripts. De plus, ces fichiers ne sont pas proposés en version compactée. En cherchant un peu, j’ai trouvé un package nommé Protoculous qui est une version compacté de Prototype et Script.aculo.us en un seul fichier ! Voilà une bonne méthode pour réduire le nombre de requête HTTP.
En remplaçant ces composants par Protoculous, le site obtient la note A pour ce point et la note globale passe à A avec un score de 90.
Le site n’est pas « encore » assez conséquent pour utiliser un CDN. Mais juste pour voir la note obtenue avec un CDN, j’ai ajouté le paramètre suivant dans Firefox (dans la page about:config) :
extensions.yslow.cdnHostnames=www.mtgaddict.net
En réglant ce dernier point le site obtiendrai la note A pour ce point et son score serait de 97. Pas mal, non ? 🙂
Il y a encore quelques points d’amélioration possibles. Mais j’ai voulu montrer comment améliorer les performances d’un site en fournissant très peu d’effort. Des pages HTML de près de 275Ko ne font plus que 25Ko. Et les temps d’affichage des pages se sont nettement réduits.
Couplé à ces optimisations, j’ai également activé le cache HTML côté serveur pour certaines pages stratégiques à contenu fixe. Si votre moteur de rendu offre cette fonctionnalité, pensez-y aussi.
https://blog.lecacheur.com/2009/05/13/yslow-comment-optimiser-son-site-web-en-quelques-minutes/DéveloppementapacheVotre site est poussif ? Le temps de chargement ou d'affichage des pages est trop long ? Avant de penser à changer d'hébergement et avant de se plonger dans le code afin d'y trouver des points d'amélioration, il est peut-être important de regarder de plus près comment sont conçues...SeBSébastien LECACHEUR23r0@laposte.netAdministratorLe weblogue de SeB
ah je me rappelle quand je jouais encore à Magic (instant nostalgie)…
maintenant je dois avoir plein de cartes dans mon grenier lol 🙂
concernant l’optimisation, les expires header ne semblent pas être bien configurés et attention à ne gzipper de javascript packé (impact sur le moteur de rendu javascript) ^^
anti-pixel,
Si tu fais un vide-grenier fait-moi signe. 😉
Les expires header me semblent corrects mis à part pour les fichiers HTML où j’ai une date d’expiration en 1981. Mais j’ai la même date si j’ajoute la ligne suivante :
ExpiresDefault « access plus 1 seconds »
Qu’est-ce qui te fait dire qu’ils sont mal configurés ?
Pourquoi le gzip impacterait le moteur de rendu Javascript ? La compression se fait au niveau HTTP.
De plus, dans ton exemple tu compresses les fichiers Javascript, non ? Voici les lignes extraite de ton article :
SetOutputFilter DEFLATE# compress content with type html, text, js, and css
AddOutputFilterByType DEFLATE text/html text/plain text/css text/javascript application/javascript application/x-javascript
En tout cas, merci pour tes remarques. 🙂
Attention, supprimer les Etags est une très mauvaise idée si ton serveur n’est pas en load balancing. La suppression des ETags n’a d’intérêt que pour les très gros sites.
En effet, les Etags en soit marchent très bien. Ils permettent d’optimiser efficacement les mises à jour de cache. Ils posent problème uniquement dans un environnement en load balancing car la valeur d’un Etag dépend du serveur qui l’a calculée. Donc, si on utilise des Etags dans un environnement ou ce n’est pas toujours le même serveur qui traite la requête, le client voit des modifs de contenu là où il n’y en a pas.
Ooops, le retour chariot m’a échappé sur mon commentaire précédent. Voici la version complète.
Attention, supprimer les Etags nèest pas une très bonne idée si ton serveur n’est pas dans un environnement en load balancing. La suppression des ETags n’a d’intérêt que pour les très gros sites. Et YSlow a été crée par Yahoo, pour Yahoo, donc pour des gros sites apriori.
En effet, les Etags en soit marchent très bien. Ils permettent d’optimiser efficacement les mises à jour de cache. Ils posent problème uniquement dans les environnements en load balancing car, avec Apache, la valeur d’un Etag dépend du serveur qui l’a calculée. Donc, si on utilise des Etags dans un environnement ou ce n’est pas toujours le même serveur qui traite la requête, le client voit des modifs de contenu là où il n’y en a pas simplement parce que cèest un serveur différent qui à traité la requête et quèil a donc renvoyé une valeur dèEtag différente pour une ressource qui nèa en fait pas changé.
Donc :
– sur des infrastructures complexes: Etags : interdits
– sur des hébergements basiques : Etags : souhaitables
Je suppose que ton hébergement est plutôt basique (sans que ce soit péjoratif). Dans ce cas, il semble que:
– soit tu nèutilises pas la dernière version dèYSlow,
– soit tu nèutilise pas le bon profil pour tes tests (les profils sont une fonctionnalité récente dèYSlow).
En effet, YSlow propose le profil « Small site or blog » (small fait référence à lèinfrastructure et non au nombre de pages), qui correspond à un site basique. Avec ce profil, qui correspond sans doute à ton cas :
• Le critère CDN est écarté,
• Les Etags ne sont pas considérés comme néfastes, au contraire (pour la raison que jèexposais au dessus).
Et là tu obtiens une très bonne note sans tricher (sans déclarer de CDN factice dans la config).
Laurent,
Merci pour ton explication sur les ETags. Je les réactiverai lors de la prochaine mise à jour du site.
Et effectivement, je n’avais pas vu que l’on pouvait choisir un profil pour les tests. En choisissant « Small site or blog » (ce qui n’est pas péjoratif ;-)), je n’ai plus de problème avec le CDN et les ETags.
Merci pour tes commentaires éclairés ! Je vais devoir réécrire un billet là dessus… 🙂
Petite remarque sur les expire headers :
pour éviter les problèmes de cache lors de la mise à jour du site, il est conseillé de versionner les scripts:
– soit comme yahoo l’indique en rajoutant un numéro de version sur le fichier script
– soit la méthode qu’on utilise chez nous : un versionning par répertoire:
dans les pages, les liens sont du types:
http://site.com/scripts/v3.4/monscript.js
Le lien en lui-même étant généré dynamiquement via une variable de configuration :
http://site.com/scripts//monscript.js (pour une jsp)
Cela permet de déployer une nouvelle version en étant sur que tous les navigateurs vont charger la bonne version du script.
Les caractères JSP ne passent pas dans les commentaires, équivalent perl:
http://site.com/scripts/$version/monscript.js
Franck,
Effectivement, c’est une bonne méthode pour la mise à jour des feuilles CSS et des fichiers Javascript. Après, je ne suis pas convaincu que ce soit applicable pour les images. C’est possible bien sûr mais je n’aime pas trop ça.
Pour reprendre ton exemple avec les JSP, il est possible d’utiliser la notation JSTL : 😉
http://site.com/scripts/${version}/monscript.js
Merci pour ton complément d’information !
Bonsoir,
est ce que quelqu’un peut m’expliquer comment mettre en place le compressage pas à pas.
J’ai cherché sur le net mais rien compris lol
Merci beaucoup
Xavier,
Ça dépend pas mal du serveur HTTP que tu utilises. Et par exemple, si tu utilises Apache, ça dépend également de la version.
Si tu utilises Apache 2.2 et que le module deflate est activé, tu peux ajouter la ligne suivante dans ton fichier .htaccess :
AddOutputFilterByType DEFLATE text/javascript application/javascript text/css application/xhtml+xml text/html text/plain application/json text/xml
Ça compressera tous les fichiers Javascript, CSS, XML, HTML, texte et JSON.
Bonjour,
Concernant les headers, j’aimerais savoir si le cache est automatiquement regénéré lorsque la source du fichier (image, css, etc.) est modifiée ? Cela me serait plutôt utile en développement, où je modifie souvent mes fichiers. Ou encore, si un jour, je veux pouvoir modifier un fichier sans supprimer manuellement son cache associé… N’est-il pas préférable d’utiliser la fonction header() de PHP ?
Concernant la compression GZip, est-ce mieux de passer par Apache plutôt que par ob_start(‘ob_gzhandler’) en PHP ?
Merci.
Hi,
About the ETags and Apache, I only remove ETags on some files. Below are my configuration:
#SetEnv APACHE_HEADER_MODULE on
#Header set P3P « policyref=\ »/w3c/p3p.xml\ » »
ExpiresActive On
ExpiresDefault A0
ExpiresDefault A29030400
Header append Cache-Control « public »
FileETag None
Header unset ETag
ExpiresDefault A604800
Header append Cache-Control « public »
#Header unset Last-Modified –> error when old image exist
FileETag None
Header unset ETag
ExpiresDefault A304800
Header append Cache-Control « proxy-revalidate »
Header append X-Robots-Tag « index, noarchive, nosnippet »
ExpiresActive Off
Header set Cache-Control « max-age=29030400, public »
FileETag None
Header unset ETag
Header set Cache-Control « max-age=604800, public »
#Header unset Last-Modified –> error when old image exist
FileETag None
Header unset ETag
Header set Cache-Control « max-age=604800, proxy-revalidate »
Header set X-Robots-Tag « index, noarchive, nosnippet »
Header set X-Robots-Tag « noindex »
Header set Cache-Control « max-age=0, private, no-store, no-cache, must-revalidate »
Header set Pragma « no-cache »
Sorry, the form eliminate the tags. So I resubmit the configuration (I subtitute « open tag » with « ] » and « close tag » with « ] »):
[IfModule headers_module]
#SetEnv APACHE_HEADER_MODULE on
#Header set P3P « policyref=\ »/w3c/p3p.xml\ » »
[IfModule expires_module]
ExpiresActive On
ExpiresDefault A0
[FilesMatch « \.(flv|ico|pdf|avi|mov|ppt|doc|mp3|wmv|wav)$ »]
ExpiresDefault A29030400
Header append Cache-Control « public »
FileETag None
Header unset ETag
[/FilesMatch]
[FilesMatch « \.(gif|jpg|jpeg|png|swf)$ »]
ExpiresDefault A604800
Header append Cache-Control « public »
#Header unset Last-Modified –] error when old image exist
FileETag None
Header unset ETag
[/FilesMatch]
[FilesMatch « \.(htm|js|css)$ »]
ExpiresDefault A304800
Header append Cache-Control « proxy-revalidate »
[/FilesMatch]
[FilesMatch « \.(pdf|ppt|doc)$ »]
Header append X-Robots-Tag « index, noarchive, nosnippet »
[/FilesMatch]
[FilesMatch « (robots\.txt|captcha\.gif|captcha\.png|captcha\.jpg|\.xml|\.php) »]
ExpiresActive Off
[/FilesMatch]
[/IfModule]
[IfModule !expires_module]
[FilesMatch « \.(flv|ico|pdf|avi|mov|ppt|doc|mp3|wmv|wav)$ »]
Header set Cache-Control « max-age=29030400, public »
FileETag None
Header unset ETag
[/FilesMatch]
[FilesMatch « \.(gif|jpg|jpeg|png|swf)$ »]
Header set Cache-Control « max-age=604800, public »
#Header unset Last-Modified –] error when old image exist
FileETag None
Header unset ETag
[/FilesMatch]
[FilesMatch « \.(htm|js|css)$ »]
Header set Cache-Control « max-age=604800, proxy-revalidate »
[/FilesMatch]
[FilesMatch « \.(pdf|ppt|doc)$ »]
Header set X-Robots-Tag « index, noarchive, nosnippet »
[/FilesMatch]
[/IfModule]
[FilesMatch « (robots\.txt|captcha\.gif|captcha\.png|captcha\.jpg|\.xml|\.php) »]
Header set X-Robots-Tag « noindex »
Header set Cache-Control « max-age=0, private, no-store, no-cache, must-revalidate »
Header set Pragma « no-cache »
[/FilesMatch]
[/IfModule]
Bonjour,
J’ai essayé un peu partout, mais avec le manque de maîtrise au pire cela ne fonctionne pas et je dois redémarrer apache.
Pourriez-vous préciser exactement le ou les fichiers à modifier et la section de ceux-ci.
J’ai essayé le .htacces du site : rien nada
J’ai a2enmod expires et là çà ne plante plus, mais çà ne change rien au niveau yslow
Je subodore que ce doit être dans les fichiers de conf de apache mais dans lequel le général celui des virutals host et dans quelle section ?
Par avance merci.
CDT PM
Question conne mais comment tu as fait pour récupérer le rapport ? J’ai install.é le addon a firefox mais je ne comprend pas ou voir le tableau que tu as eu !
Ok il fallait installé firebug !
Merci pour cet article, je pense effectivement que mon site n’a pas une optimisation optimale pour les moteurs de recherche.
Maintenant le peu d’image que j’ai, me plombe beaucoup aussi…