Accélération du chargement des pages avec Drupal

S'il faut bien reconnaître une vertu à WanadooOrange, c'est que la pauvreté abyssale de leur temps de réponse et certaine caractéristiques un peu "louche" de leurs débits, permettent de mettre la lenteur du chargement de certains sites (dont celui-ci) qui seraient, avec un opérateur normal, sûrement passé inaperçu...

Et 10 secondes pour charger cette page d'accueil me paraissait un peu... long. Alors je me suis donné 10 minutes chrono pour voir ce qui se passait et éventuellement régler cela.

Cet article n'est plus valide pour la version 6.x de Drupal où le patch d'agrégation des scripts a été intégré.

Pour investiguer, j'ai simplement activé l'indispensablissime extension FireBug (encore merci Mose), et utilisé l'onglet net pour avoir un graph précis du temps ET du moment de téléchargement de chacun des éléments de la page. Dans la mesure où j'ai activé le pipelining sous FireFox, c'est à dire la capacité de télécharger jusqu'à 30 éléments en même temps, je m'attendais à avoir un graphique logiquement constitué de barres démarrant au même moment par bloc de trente. Pour ne pas fausser le jeu, j'ai pris soin de désactiver le cache de FireFox.

Or surprise, si FireFox parallélise très bien le chargement des images, il ne le fait pas du tout pour les scripts et des feuilles de style. Et là cela pose un vrai problème car de plus en plus de frameworks, comme Drupal, marchent par modules (ou plugins) qui chacun comporte SON fichier css, et SON fichier javascript. Résultat, pour artisan :

TypeNombre
de
fichier
Volume (ko)temps (s)débit (fictif)
Javascript11313.588.65
CSS13101.536.53
Images40780.95581.67
Parlant mais pas forcement compréhensible du premier coup d'œil. Comment 78ko constitué de 40 images, se chargent donc au minimum 3 fois plus rapidement que 11 fichiers javaScript qui pèsent moins de 2 fois ce poids. Et c'est pire si l'on compare les débits (fictifs) qui donnent un script 10 fois plus lent à charger qu'une image...

La raison est simple et multiple :

  • Les fameux temps de réponse calamiteux d'Orange.
  • Le fait que FireFox semble bidouiller les scripts après le chargement (cela prends un peu de temps)
  • Le fait que FireFox ne chargement pas les CSS/JS en même temps.
Et c'est ce dernier point qui pose le plus de problèmes. Car lorsque firefox lance le chargement de toutes les images en même temps, le mauvais temps de réponse unitaire d'Orange est en quelque sorte "mutualisé". Il est long, mais le même pour tous, et donc les retours se font en même temps, et les images arrivent rapidement une fois la connexion établie.

Mais comme firefox ne parallélise pas CSS et JavaScripts, chaque temps de réponse se trouve ainsi ajouté au temps précédent. Le résultat en est que pour ces fichiers de petite taille, le débit très élevé de l'ADSL2, n'arrive pas à rattraper ce retard.

Petite parenthèse, débit élevé... pas tant que cela ! 80ko/s pour des images, ce n'est pas logique pour de l'ADSL2. Sauf si, bien sur, le système orange est configuré pour que le débit augmente au fur et à mesure de l'avancement du téléchargement. Un temps de réponse lent, un débit qui arrive à son maximum après un certain temps (d'après mes tests le débit est au max après les premiers 100ko) et donc pour une certaine taille de fichiers... C'est comme si les techniciens d'Orange avaient configuré leurs systèmes pour privilégier le téléchargement de gros fichiers au détriment du surf sur le web... Bizarre ;-) Faut pas s'en étonner cat d'un, la première chose que M. Toto fait pour tester sa nouvelle MachinBox c'est... télécharger un fichier, genre un gros ;-), donc c'est bon pour l'image d'orange. De deux, ralentir les petits fichier cela permet de faire ni vu ni connu tourner la navigation web avec 10 fois moins de bande passante, c'est économique (pour Orange, bien sur) et ça permet d'avoir assez de Jus pour les M. Toto qui pompent comme des malades. De trois, c'est bien pratique lorsque vous appelez le SAV :
Bonjour M. Orange, j'ai pas de débit, mon web est lent
Allez sur un site et téléchargez un gros fichier, quel débit avez vous ? (véridique j'y ai eu droit...)
1.2Mo M. Orange !
C'est donc que votre ligne va bien, cela doit venir de votre OS... Bonne journée...

Dans la série prenez-moi pour un âne ;-)

Bref, fin de la "petite" parenthèse, on est pas la pour parler d'Orange, car maintenant que le diagnostique est établi, quelle est la cure ? Pas du côté de FireFox en tout cas, n'ayant pas très envie de mettre le nez dans le système de pipelining même si la vraie solution est là. Pourquoi cela ne fonctionne pas ? un des nombreux mystère de FireFox.

Concernant Artisan, qui utilise Drupal, la solution pour les CSS est toute trouvée. Il suffit, à partir de la version 5.X, d'aller dans l'administration/configuration/performances et d'activer l'agrégation des CSS. Le rôle de cette option est de fusionner, sur le serveur, toutes les feuilles de styles en un et un seul fichier. Du coup, c'est la fin d'une multitude de petits CSS qui nous prenait temps de temps.

Ce qui est faisable pour le CSS, doit aussi l'être pour le JavaScript. A savoir, fusionner tous ces fichiers en un seul. Et c'est bien une fonctionnalité qui existe... dans la version 6 ;-) Fort heureusement, une bonne âme a back-porté cette fonctionnalité sur la version 5.2. Le patch est disponible ici. Il suffit dés lors d'aller à la racine de Drupal et d'appliquer le patch

patch -p0 < js_aggregation_drupal_5_2.patch

Répondez (n)on à la dernière question. Ensuite refaites un tour dans l'administration/configuration/performances et devrait apparaître l'activation de l'agrégation des javascript. Il suffit de l'activer pour qu'on prochain coup, comme pour le CSS, cela soit pris en compte.

Comme pour le CSS, l'agrégateur JS va en plus de fusionner les fichiers, tenter de compresser le résultat en supprimant tout ce qui ne sert à rien. Or, certaines fois, cela ne marche pas génial. Il est donc possible d'éviter cette compression en remplaçant dans le fichier ./includes/common.inc
// Ancienne ligne : $contents .= _drupal_compress_js(file_get_contents($path). ';');
// A remplacer par ce qui suit :
$contents .= file_get_contents($path);
$contents .= "\n//--\n";

Il ne reste maintenant plus qu'à relancer un chargement de la page avec FireBug en position Net pour voir le résultat :

TypeNombre
de
fichier
Volume (ko)temps (s)
Javascript170.234
CSS1300.652
Images40780.96

Résultat excellent n'est-ce pas ? Plus de 15 fois plus rapide pour les Javascripts et 2.3 fois plus rapide pour le CSS.

Dab (non vérifié), le ven, 05/10/2007 - 16:27

Intéressant ça, je n'avais pas constaté ou plus exactement pas remarqué de ralentissement suspect pour les petits fichiers ... Le pb existe quelque soit le protocole ?
Tes mesures ont bien sûr été faites sans proxy ?

Yoran, le ven, 05/10/2007 - 17:35

Oui, le test a été fait sans proxy, avec une petite routine java que j'avais écrite pour comprendre le phénomène. L'idée est de mesurer la vitesse obtenue par tranche de 10ko de données. La première vitesse est moyenne (reçus/(T-T0)) et la seconde est instantanée (blocRecu/TempsReception).

    Reçu  moyenne instantanée
    -------------------------
    9842  289     374
    22802 345     360
    34098 358     446
    47282 454     1280
    58802 529     1645

Tu vois bien que la vitesse instantanée est relativement basse au démarrage puis va en augmentant pour atteindre sa vitesse max.

L'avantage de la méthode est que tu privilégie le débit psychologique au débit réel. Vu que 80% de l'activité ce fait sur le web, mais que lorsque tu testes ta ligne, tu va prendre un gros fichier pour avoir le temps de voir, dans 80% des cas, tu n'occupes que 1/4 au mieux de la BP réelle.

Une autre bonne preuve de cela est que lorsque je fait un tunel sur une dédibox (dédiée free) et que je me connecte via un proxy (type ssh), le débit montre beaucoup plus vite.

Dab (non vérifié), le ven, 05/10/2007 - 19:30

Je vois que tu as bien creusé la question :)
Je ne comprend pas bien ce que tu appeles la vitesse instantannée et sutout comment tu récupère les valeurs blocRecu/TempsReception.
Intéressante cette offre dedibox, mais comment ça le débit monte beaucoup plus vite ? tu veux dire que ssh n'est pas soumi aux règles de QOS ?

Yoran, le ven, 05/10/2007 - 19:36

Ben lorsque ssh est connecté, tu n'es pas soumis aux règles "début de connexion". Elle est établie une fois pour toute.

Pour ce qui est de mes calculs c'est assez simple, j'ai une classe Download qui m'envoie un événement onReceive(byteReceived) tout le X octets (dépendant du buffer de téléchargement). Moi ce que je fait, c'est que j'ajoute des "byteReceived" à un accumulateur, et lorsque cet accumulateur dépasse 10ko, je calcule une vitesse "instantanée" (une moyenne sur les 10 derniers kilos reçus en fait), sous la forme Vi=accumulateur(Tn-Tn-1). Avec Tn l'heure en ms au moment de la prise de mesure, et Tn-1, celui de la mesure d'avant. Voilà en gros comment ça tourne.

Maintenant pour le "ça monte beaucoup plus vite", si là je dois attendre le 60° kilo pour être au max de la ligne, sur la dedi, c'est quasi au 1° kilo.

Dab (non vérifié), le ven, 05/10/2007 - 23:53

ok merci pour ces précisions, en gros 10 k / le temps que ces 10 ko ont pris pour se télécharger, c'est ça ?
Et ce ne peut pas être un mécanisme lié à TCP ? genre qui augmenterai sa fenêtre en fonction du nombre d'octet à transmettre, je sais que ça existe dans l'autre sens (si pb tcp alors diminution de la fenetre)
Ca existe pas chez les autres FAI ?
'scuse pour toutes ces questions ... je trouve ça très intéressant :)
...
Je viens d'avoir une idée horrible, tu n'as pas de Qos sur ta sortie internet ? :))

Yoran, le sam, 06/10/2007 - 00:32

Oui c ça :-) Quoi, elles sont pas claires mes explications ? -;)

Pour le QoS, nan, j'utilise pas ces machins moi, pas le besoin ;-) Y'a bien que telle fonction sur mon routeur mais je ne l'ai jamais activé.

Sinon, oui, c'est peut-être un truc lié à TCP que je ne connais pas, ce serait pas étonnant vu l'étendue de mes connaisssances sur le sujet. En revanche, si je fais un simple ping (pour avoir le temp de réponse) suivi d'un download avec wget, sur wanadoo j'ai un profile du genre :

64 bytes from ftp.club-internet.fr (194.158.99.22): icmp_seq=1 ttl=54 time=31.6 ms
    0K .......... .......... .......... .......... ..........  0%  455K  12:49
   50K .......... .......... .......... .......... ..........  0% 1.14M   5:00
  100K .......... .......... .......... .......... ..........  0% 1.36M   4:11
  150K .......... .......... .......... .......... ..........  0% 1.32M   4:18
  200K .......... .......... .......... .......... ..........  0% 1.40M   4:04

sur la dedibox, même url

64 bytes from ftp.club-internet.fr (194.158.99.22): icmp_seq=1 ttl=53 time=1.07 ms
  0K .......... .......... .......... .......... ..........  0% 9.77M   0:34
   50K .......... .......... .......... .......... ..........  0% 12.2M   0:27
  100K .......... .......... .......... .......... ..........  0% 9.77M   0:34
  150K .......... .......... .......... .......... ..........  0% 12.2M   0:27
  200K .......... .......... .......... .......... ..........  0% 12.2M   0:27

et enfin sur une freebox adsl2 d'un ami :

   64 bytes from ftp.club-internet.fr (194.158.99.22): icmp_seq=1 ttl=53 time=8.18 ms
   0K .......... .......... .......... .......... ..........  0% 1.40M   4:04
   50K .......... .......... .......... .......... ..........  0% 1.81M   3:08
  100K .......... .......... .......... .......... ..........  0% 1.53M   3:43
  150K .......... .......... .......... .......... ..........  0% 1.63M   3:29
  200K .......... .......... .......... .......... ..........  0% 1.95M   2:54

Chercher l'erreur ;-) Ok la dedi est très rapide, mais le ping est 4x plus rapide sur la freebox que sur wanadoo, et le temps de monté est quasi direct sur la free (1.4mo à 0K) et à 455k chez wanadoo...

Dab (non vérifié), le sam, 06/10/2007 - 01:29

time=1.07 ms argh... free héberge club-internet ?
Si je fais le même ping j'ai 55 ms sans download :( mais bon c'est pas dramatique, tant qu'il y a pas trop de perte de paquets :)

Yoran, le sam, 06/10/2007 - 01:34

Nan, j'en doute (que free héberge CI ;-). Mais j'ai revérifié, c'est bien les bons temps.. et les bons débits... Mais bon, c'est sur la dédibox ça, le dernier dump est plus proche des résultats standards d'un freenaute parisien.

Dab (non vérifié), le sam, 06/10/2007 - 02:12

mouai ... moi qui était tout content de mes tout nouveau 2Mo remplacant les pauvres 512k précédents :(

Yoran, le sam, 06/10/2007 - 02:35

Ben ça dépends d'où tu te trouves. En pleine campagne, même avec ces latences, cela reste le bonheur l'ADSL :)

Dab (non vérifié), le sam, 06/10/2007 - 11:56

Oui c'est vrai, quand je pense à mes débuts sur internet ... à 4ko/s pied au plancher, ça laisse rêveur

anti-pixel (non vérifié), le lun, 28/04/2008 - 14:39

billet intéressant, même si on voit que tu as fait tout ça en 10mn (fautes de frappes ?).
il me semble que contrairement aux images et autres css chargés de manière parallèle, les fichiers javascript sont chargés un par un (ou 2 par 2), mais je ne suis pas très sur.
A noter l'existence de l'extension yslow pour firebug (extension pour extension !), utile pour suivre le temps de chargements, le nombre de requête http, etc

Yoran, le mar, 29/04/2008 - 10:44

En 10 minutes, c'est un peu exagéré vu le volume d'informations. Les fautes de frappes, c'est plus ma marque de fabrique, mais je ne suis jamais contre une correction ;-)

Pour les chargements, les JS sont effectivement chargés un par un, c'est d'ailleurs le sujet de mon billet, ou alors je n'ai pas compris où tu veux en venir.

Merci pour cette extension, très intéressant, elle tombe à pic pour un projet en cours.

Publier un nouveau commentaire

Le contenu de ce champ sera maintenu privé et ne sera pas affiché publiquement.
  • Les adresses de pages web et de courriels sont transformées en liens automatiquement.
  • To highlight piece of code, just surround them with <code type="language"> Your code &tl;/code>>. Language can be java,c++,bash,etc... Everything Geshi support.
  • Les lignes et les paragraphes vont à la ligne automatiquement.

Plus d'informations sur les options de formatage

CAPTCHA
Cette question est là pour déterminer si vous êtes humain ou pas...