ySlow et performances de drupal & wordpress | anti-pixel | développeur web

ySlow et performances de drupal & wordpress

// le 01 mai 08 dans dev

ySlow et performances de drupal & wordpress

Comment améliorer la rapidité d’affichage de son site web, et plus spécifiquement un site fonctionnant sous wordpress ou drupal ? C’est la question que je me suis posé récemment…

Après avoir optimisé le site au moment de sa conception :

  • réduire le nombre de fichiers javascript et css
  • optimiser les images pour le web
  • utiliser des fichiers minifiés/packés pour les framework javascript
  • passer les png dans PngOptimizer
  • coder le xhtml et surtout le css proprement
  • etc

la première solution à laquelle on pense est immédiatement le système de cache. Présent sur tous les CMS (sûrement, mais au moins pour drupal, wordpress et spip), il permet d’optimiser l’affichage par la mise en cache des pages au format html, ce qui évite tous les traitements en base de données pour aller chercher le contenu dynamiquement (rappelons qu’un fichier statique html sera toujours plus rapide qu’un fichier généré).

Drupal dispose de son propre système de cache, avec 2 réglages. Le niveau normal est impérativement à activer dès que le site est en production tant il améliore les performances.

D’ailleurs voici un petit graph’ :

drupal-vs-joomla-rps

Joomla est juste là pour avoir un élément de comparaison, on voit que sans cache, Drupal est capable de fournir 13 pages par seconde, avec le cache, cela passe à 66 pages par seconde !! On voit aussi qu’en activant, en plus, la compression gzip, drupal peut fournir 67 pages par seconde, la différence est presque imperceptible, mais j’y reviendrai plus tard.

Le niveau aggressif est incompatible avec de nombreux modules (notamment Organic Groups) ce qui le rend peu intéressant. Ce cache peut être compléter/remplacer par un module supplémentaire du type : boost

Pour Wordpress, il faut installer un plugin comme wp-cache ou wp super cache.

Bref, que peut-on faire en dehors de ces solutions ?

Tout d’abord, si vous n’avez pas Firebug, le plugin de Firefox, téléchargez-le ici. Téléchargez ensuite ySlow, cet outil, développé par Yahoo permet de tester la performance d’un site et son optimisation en terme de rapidité. Il rajoute un onglet à Firebug.

Commençons l’optimisation en suivant les critères de ySlow (en désordre) :

Use a CDN

Peu de chances que l’on dispose d’un CDN, donc il faut se débarasser de se critère pour ne pas fausser l’analyse. Ouvrez un onglet firefox, tapez l’adresse about:config, clic droit, Nouvelle chaîne de caractère, tapez extensions.firebug.yslow.cdnHostnames puis l’adresse de votre site web. Voilà, on a un premier A, même si pour le moment, on n’a rien optimisé du tout !

Configure ETags

Un Etag (entity tag) est une en-tête http renvoyée par le serveur web pour déterminer si le contenu à changer pour une URL donnée. il contribue au système de cache. Malheureusement, ces Etags sont souvent spécifiques au serveur et intègre une valeur unique, rendant le système inutile voire contre-productif par l’ajout de requêtes http inutiles. Désactiver ce système améliore donc les performances. Pour cela, direction le fichier .htaccess, ajoutez le code

FileETag none

Et un deuxième A dans ySlow !

Add an Expires header

Précisez de longs délais pour l’expiration des en-têtes http. Ainsi, les fichiers ne seront pas systématiquement vérifiés lors de l’affichage de la page et vous économiserez un paquet de requêtes http. Pour cela, ajoutez ce code dans le .htaccess

# Set long expire headers for better browser caching
<IfModule mod_expires.c>
ExpiresActive OnExpiresByType 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"
</IfModule>

Cela devrait vous donner une bonne note, mais probablement pas un A, notamment à cause des scripts externes, comme ceux de Google Analytics, un B ou C, c’est déjà pas mal !

Put CSS at the top & Put JS at the bottom

Mettez tous les CSS dans les balises HEAD et les JS juste avant le </body> (lorsque c’est possible). Cela paraît évident mais cela est dû au mécanisme de téléchargement des différents fichiers du site (et de leur parallélisation) mais aussi au moteur de rendu du navigateur. En effet, il peut parfois être très désagréable d’avoir un rendu “progressif” au fur et à mesure du chargement de la page (exemple type : les pages myspace). Pour éviter cela, placez tous les CSS dans les balises head, cela permettra déjà de faire que tous les styles soient chargés.

Pour les javascript, c’est plus compliqué. Il faudrait théoriquement les placer en bas de page avant le </body> car les javascripts sont plus longs à charger (et bloquent la parallélisation des téléchargements mais je n’en suis pas sûr). Malheureusement, certains librairies javascript nécessitent d’être importées en haut de page pour pouvoir utiliser leur syntaxe plus bas, rendant impossible de placer tous les scripts en bas de page. Ce qu’il est important de retenir, c’est de placer les scripts externes en bas de page (les scripts google analytics doivent obligatoirement se placer avant le </body> pour ne pas bloquer le rendu de la page), et le plus souvent que possible.

Make fewer HTTP requests & Gzip components & Minify JS

Et là, on rentre vraiment dans le gros morceau de l’optimisation, c’est à dire : le nombre de requêtes http total et le poids des fichiers. Comment résoudre ces problèmes va vraiment dépendre de votre configuration du site et du serveur, je vais donc prendre pour exemple, les 2 cas que j’ai fait cette semaine, un site wordpress hébergé chez OVH (celui-ci ^^) sans possibilité d’agir sur la compression gzip, et un site du boulot sous Drupal (amikuze-entreprendre.com).

Pour Drupal

Commençons par le site sous Drupal. De nombreux modules étant installés, chacun possède ses CSS et JS, peu lourds, mais augmentant énormement le nombre de requêtes http. Ces fichiers sont pour la plupart ni minifiés, ni packés, même la version de jquery intégrée à Drupal.

Première action : aller dans l’administration de drupal, rubrique performance et activer l’aggrégation et la minification des fichiers css. Et oui, drupal intègre dès sa version 5 cette fonctionnalité. Tous les commentaires, espaces et retour à la ligne sont enlevés, les fichiers sont regroupés en un seul, mis en cache. Parfait, rien à dire. Dans mon cas, ma page d’accueil présente encore 3 fichiers CSS distincts, le fichier aggrégé, mon fichier reset qui est à part (une erreur de jeunesse drupalienne) et un CSS spécifique au nuage de tag qui n’est donc présent que sur la page d’accueil et pas intégré au fichier global.

Deuxième action : La même fonctionnalité pour les javascripts serait évidemment très utile. Elle est d’ailleurs intégrée à Drupal version 6. En attendant, il existe plusieurs solutions pour avoir cette fonctionnalité sur Drupal 5, certaines nécessitent de patcher le core de Drupal. Moi, je préfère la solution en Module. Et c’est javascript aggregator la solution. Celui-ci ajoute l’aggrégation des fichiers javascripts à partir du menu Performance de Drupal et propose même de spécifier certains fichiers que l’on ne voudrait pas aggréger. Le système de minification est sensé supprimer les commentaires mais ne fonctionne pas, ce qui est gênant. Direction donc ici, où un drupalien a proposé d’intégrer le script de jsmin à ce module, qui fonctionne du coup à la perfection (je l’ai pour ma part modifié un peu pour maximiser la minification). Ne pas oublier d’ajouter dans son fichier template.php, au dessus de echo $scripts;

<?php
  if(module_exists('javascript_aggregator')) {
    $scripts = javascript_aggregator_cache($scripts);
  }
?>

Résultat de ces 2 étapes, un nombre de requêtes http réduit, des fichiers plus légers. Il ne reste qu’à accentuer la compression des fichiers. Pour cela, direction le fichier .htaccess (cette étape nécessite d’avoir le mod deflate activé sur apache) et ajoutez :

# Below uses mod_deflate to compress text files. Never compress binary files.
<IfModule mod_deflate.c>
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
<IfModule mod_headers.c>

# properly handle requests coming from behind proxies
Header append Vary User-Agent
</IfModule>
</IfModule>

# Properly handle old browsers that do not support compression

<IfModule mod_deflate.c>
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html

# Explicitly exclude binary files from compression just in case
SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|pdf|swf|ico|zip)$ no-gzip
</IfModule>

Voilà le graph final :

yamikuze

Pour finir avec Drupal, un autre graphique. Alors que le premier histogramme, nous montre clairement que la compression gzip n’affecte pas les performances en terme de processus et de rapidité, celui-ci nous montre que par contre, en terme de poids de fichiers et donc de bande passante, l’optimisation est très utile.

drupal-vs-joomla-length

Pour Wordpress

Passons maintenant à Wordpress :

Comme je l’ai expliqué, je n’ai pas vraiment la main sur la compression gzip avec mon super hébergement cheap ovh. Il me reste donc la solution de gérer la compression gzip à un autre niveau, du côté php pour être plus précis. Et pour gérer tout ça d’un seul bloc, j’utilise la version du merveilleux speedy php pour wordpress, le plugin wp-speedyphp. Installez le, activez-le puis configurez le à partir de l’onglet qu’il ajoute. Ce module fournit une page de test et nécessite ensuite d’être activé à partir de sa propre page. Et là, magie, tous les CSS et JS sont minifiés, aggrégés en un fichier et gzippés. Il est à noter qu’activer la compression gzip sur le serveur est une meilleure pratique, à recommander dans le cas de gros sites à haut trafic.

Le résultat pour ce site : A, 92/100 (j’ai pris comme référence la page labo car j’ai un lien vers une vidéo youtube sur mon accueil en ce moment qui fausse les résultats), et la page de cet article devrait être à A, 90/100. Pas mal. Des techniques à généraliser, et à intégrer en début de projet pour un meilleur résultat.

yslowantipix

8 Réponses à l'article “ySlow et performances de drupal & wordpress”

Atteindre directement le formulaire pour laisser un commentaire

  1. 1

    Merci bcp, car cela m’a permis de resoudre mes problemes sur mon site.

    http://www.webdevonlinux.fr

    par robert le 05 avr 09 à 18 h 52 min

  2. 2

    J’ai trouvé cette extension vraiment sympathique même s’il faut relativiser son utilité.

    En très peu de temps, j’ai pu passer le score d’un site de 61 à 97. Pour ceux que ça intéresse, j’ai fait un compte-rendu : http://blog.lecacheur.com/2009/05/13/yslow-comment-optimiser-son-site-web-en-quelques-minutes/

    par Seb L. le 13 mai 09 à 15 h 14 min

  3. 3

    En effet, il faut relativiser son utilité, mais le fait qu’il donne une note permet de voir immédiatement les effets de l’optimisation… En plus, la nouvelle version est quand même plus sympathique au niveau de son interface…

    Par contre, concernant ce que j’ai pu lire/voir sur ton site, attention à supprimer tous les appels 404 (fichier non trouvé) qui impactent considérablement les performances.

    De même, l’utilisation de librairie « packée » est aussi à proscrire, car elle impacte le moteur de rendu javascript. Il vaut donc mieux préférer la solution fichiers javascript compilés, minifiés et gzippés (et si possible à partir d’un CDN comme celui de google code).

    Pour continuer l’optimisation, il faut ensuite s’intéresser aux nombres de requêtes SQL, mais c’est une autre histoire…

    par anti-pixel le 13 mai 09 à 16 h 53 min

  4. 4

    Hello,

    Merci pour cet article, d’ailleurs très bien écrit.

    j’ai un gros soucis de lenteur, j’utilise le mauvais couple WordPress+OVH, la home est vraiment longue à charger, malgré avoir changé pas mal de trucs (elle est passé de plus de 15sec à 5sec… loin du compte encore)

    Bon, je suis un noob, donc certains trucs simples deviennent compliqués pour moi, en voici quelques uns :

    - j’ai inséré « FileETag none » dans le .htaccess mais apparement rien ne change, j’ai juste fait copier/coller à la suite du code depuis mon BlocNote, est-ce suffisant ?

    - j’ai insérer également ton code
    , idem, mm méthode et pas de résultats

    - concernant le plugin Speedyphp, je l’avais installé hier sans lire ton blog sans succès, je viens de le refaire, mais comme hier, après avoir saisi ma config, je passe au « Test », réponse :
    « PHP Speedy didn’t find any JavaScript or CSS »
    Beurk, y-a-t-il qq chose d’autres à activer ? par exemple je n’est aucun idée d’où ^peuvent être mes « Library », j’utilise le theme Forexpress modifié.

    Bref ça fait un max de questions, si tu as un moment pour m’aider c’est cool :)
    Je continue les recherches de mon côté.

    ++

    par FisherPrice le 30 mai 09 à 14 h 37 min

  5. 5

    On est tous des noobs de quelqu’un ^^

    C’est vrai que l’on voit quelques lourdeurs à l’affichage de ton site en cas de première visite ou de cache désactivé. Pourtant, ta page d’accueil fait 426 Ko ce qui est acceptable… Pourtant, on a la même config, donc…

    Pour les Etags, la ligne indiquée devrait suffire (mais cela n’améliorera pas les performances de manière sensible à mon avis…). Bizarre que le serveur ne réagisse pas à ta modification sur le fichier .htaccess, normalement c’est assez radical : soit ça marche, soit ça plante le serveur (erreur 500 dans le cas d’une erreur de frappe ou d’une fonction non reconnue par ton serveur). Je ne peux pas débugguer sans voir ton environnement de travail mais je te propose de vérifier que le fichier .htaccess est bien actif (en tapant un truc bidon tout d’abord pour vérifier que cela plante bien le serveur, puis de tester en mettant uniquement la commande relative aux Etags, pour tester le résultat…).

    En ce qui concerne SpeedyPHP, là j’ai trouvé qu’il y avait réellement une différence sensible dans le chargement… A priori, cela devrait fonctionner… Tu n’as rien à cocher au niveau de tes librairies (tu utilises jquery comme moi, mais cela ne pose pas de problèmes…). Je me souviens moi aussi d’avoir eut droit à l’erreur « PHP Speedy didn’t find any JavaScript or CSS » mais j’ai dû l’esquiver car cela ne m’a pas laissé de grand souvenir… Peut-être en désactivant/réactivant le module pour tester le résultat ? (débuggage à la microsoft…)

    Si tu arrives à le faire fonctionner, je te conseille de remplacer tes fichiers javascript « packés » (ceux qui ont subit une compression et commencent par eval(function(p,a,c,k,e,r))) par les fichiers normaux. Ils seront minifiés par speedyphp et gzippé par le serveur, cela marchera mieux…

    Après, il te reste à optimiser les requêtes PHP et SQL, mais pas sûr que tu puisses le faire avec un plugin.

    Enfin, si malgré tout ça, cela reste lent, cela peut venir des tes voisins de serveur (et oui, il y a quelques milliers de voisins sur un serveur mutualisé…), il ne te restera qu’à investir dans un serveur dédié !!!

    Dernier détail, tes premières balises META dans ton template sont inutiles, le plugin de SEO en générant automatiquement (mais cela n’a pas d’incidence sur les performances)…

    Voilà, en espérant t’avoir aidé, bon courage ^^

    par anti-pixel le 04 juin 09 à 16 h 27 min

  6. 6

    Article sympathique, cependant on peut trouver d’autres configurations et astuces. Perso. j’ai trouvé les armes ultimes pour augmenter la réactivité (http://bit.ly/79fxkr)

    par Des Geeks et des lettres le 13 déc 09 à 23 h 51 min

  7. 7

    Merci pour ce petit tutoriel et surtout pour l’explication des FileETag :)

    par Loïc le 12 avr 10 à 11 h 50 min

  8. 8

    De rien :)

    par anti-pixel le 12 avr 10 à 14 h 03 min

Envie de discuter ?

Laisser un commentaire