Bonjour Thiébaut, je découvre à mesure que je réponds :)
On est dans un effet de bord qui peut mener au désastre... Les constructions doublons/antidoublons ont l’air plus efficaces que celles à base d’#ARRAY
mais ce n’est pas une différence majeure. Là où ça tue, c’est quand on se retrouve à faire sans le savoir des boucles qui génèrent des quantités importantes de caractères parasites. Et cela arrive très facilement avec les #ARRAY
.
Il y a quelques temps j’ai remplacé un code PHP tout sale intégré à ma homepage par du joli code SPIP à base d’#ARRAY
. J’avais l’espoir que le cache soit mieux géré et par conséquent, que ma page se charge plus vite (c’est ce que disent tous les articles : « ne mixez pas le PHP et le langage SPIP, c’est un péché mortel »). Mais horreur, ma page mettait maintenant des secondes à se charger. J’en ai déduit abusivement que les #ARRAY
étaient inexploitables dès lors que les boucles faisaient beaucoup de tours.
En fait ce n’est pas tout à fait ça. Certes les codes à base de #ARRAY
ne sont pas des foudres de guerre, mais quand on les utilise on peut se faire abuser par les espaces et les retours chariots qu’on est amené à insérer sans même s’en douter.
Pour commencer, toutes les boucles de la forme <BOUCLEx(){}> blabla </BOUCLEx>
émettent des caractères à chaque tour. Au minimum, il y a un retour chariot à chaque tour => un octet donc. Par conséquent, la boucle suivante qui boucle sur une un groupe de 1442 mot-clés sans rien faire :
<html><head></head><body>
<BOUCLE_motsarticles(MOTS){id_groupe=11}>
</BOUCLE_motsarticles>
</body></html>
produit un résultat d’un peu plus de 1442 octets.
On ne fait pas en général des boucles à beaucoup de tours de ce type, sauf si on utilise des #ARRAY
car dans ce cas, l’objectif est d’affecter des variables dans la boucle pour faire le tri plus tard. Elles ressemblent donc à ça :
<BOUCLE_x(TABLE){critères}>
#SET{tableau,#GET{tableau}|push{#BALISE}}
</BOUCLE_x>
Cette boucle n’est pas censée afficher quoique soit, et on ne s’attend pas à ce que des caractères soient émis. D’ailleurs, lorsque le compresseur HTML est activé, la boucle ne sort effectivement rien.
Mais comme toutes les boucles dans la forme décrite précédemment, elle émet des caractères parasites. Dans cet exemple, c’est un retour chariot à chaque tour de boucle. En pratique donc :
<html><head></head><body>
#SET{tableau,#ARRAY}
[(#REM) Passe en revue les 1442 mots du groupe 11]
<BOUCLE_motsarticles(MOTS){id_groupe=11}>
#SET{tableau,#GET{tableau}|push{#ID_MOT}}
</BOUCLE_motsarticles>
</body></html>
produit une page d’un peu plus de 1442 octets que le compresseur HTML va redescendre à 40 octets.
Disons que là mon écriture était serrée et que je veuille faire « plus propre » en indentant :
<html>
<head>
</head>
<body>
#SET{tableau,#ARRAY}
[(#REM) Passe en revue les 1442 mots du groupe 11]
<BOUCLE_motsarticles(MOTS){id_groupe=11}>
#SET{tableau,#GET{tableau}|push{#ID_MOT}}
</BOUCLE_motsarticles>
</body>
</html>
Booom ça me pète à la figure : la page produite fait maintenant 18.4ko dont 1.4ko de retours chariot et 17ko d’espaces inutiles !
Le compresseur HTML va toujours redescendre la page à 40 octets, mais malheureusement, il fait avec une performance désastreuse. Il met 3.7s à supprimer ces 18.4ko de cochonneries. Cette petite boucle de rien rend mon site presque inexploitable ! Par chance, je n’indente pas beaucoup :)
Si la base est petite (quelques dizaines d’articles, quelques mot-clés etc.) il n’y a pas de problème, les boucles ne feront jamais beaucoup de tours. Il n’y aura pas beaucoup de caractères parasites et tout se passera bien. Mais si le site commence à prendre de l’importance avec des milliers d’éléments, c’est critique.
Il y a plusieurs solutions pour s’en sortir lorsqu’on a besoin de faire des boucles à beaucoup de tours :
- utiliser des constructions de boucle qui ne produisent pas de caractères parasites comme tes boucles à doublons/antidoublons
- ne pas indenter, tout sur la même ligne
- minifier soi-même avec la balise
#FILTRE
En ce qui concerne le compresseur HTML de SPIP :
SPIP 3 utilise la librairie Minify de Stephen Clay. Elle a quasiment une performance quadratique : doubler le nombre d’espaces à supprimer lui prend presque 4 fois plus de temps. J’ai l’impression de voir où est le problème dans le code : les protections de SCRIPT, STYLE, PRE, TEXTAREAs et INPUT utilisent des expressions régulières où on recherche d’éventuels espaces avant et après ce qui tue la perf. Je ne vois pas l’intérêt de rechercher des espaces avant et après, mais comme les auteurs de SPIP n’y ont pas touché, c’est peut-être plus compliqué que ça...