<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Communauté Magento francophone &#187; Javascript</title>
	<atom:link href="http://www.wikigento.com/category/javascript/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.wikigento.com</link>
	<description>Optimisation de sites E-commerce, hébergment Magento</description>
	<lastBuildDate>Mon, 30 Jan 2012 16:33:08 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Javascript &amp; PHP, deux goulots d&#8217;étranglement du Web ?</title>
		<link>http://www.wikigento.com/optimisation-lampzendmagento/javascript-php-performances/</link>
		<comments>http://www.wikigento.com/optimisation-lampzendmagento/javascript-php-performances/#comments</comments>
		<pubDate>Sun, 20 Dec 2009 12:52:45 +0000</pubDate>
		<dc:creator>Philippe Humeau</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Optimisation LAMP/Zend/Magento]]></category>
		<category><![CDATA[Php/Zend/Magento]]></category>
		<category><![CDATA[compilation php]]></category>
		<category><![CDATA[interprétation php]]></category>
		<category><![CDATA[langage interprété]]></category>
		<category><![CDATA[performance Javascript]]></category>
		<category><![CDATA[performance magento]]></category>
		<category><![CDATA[performance php]]></category>
		<category><![CDATA[performance zend]]></category>

		<guid isPermaLink="false">http://www.wikigento.com/?p=1372</guid>
		<description><![CDATA[Cet article parle des performances de Javacsript et de celles de PHP, qui sont au coeur du Web moderne mais en fait pas forcément optimisés.]]></description>
			<content:encoded><![CDATA[<h1 style="text-align: justify;"><strong>Javascript et PHP sont-ils des sources de ralentissements ?</strong></h1>
<p><BR></p>
<p style="text-align: justify;">Je vais me faire des amis avec un titre comme celui-là <img src='http://www.wikigento.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p style="text-align: justify;">Maintenant, au-delà de la provoque, menons une analyse objective.</p>
<p style="text-align: justify;">Nous avons, de nos jours, (au moins) deux gros goulots d’étranglement lorsque nous nous adressons à un site Web :</p>
<ul style="text-align: justify;">
<li>Javascript du coté du client</li>
<li>PHP du coté du serveur.</li>
</ul>
<p style="text-align: justify;">Analyse…</p>
<h2 style="text-align: justify;"><strong>Parlons de Javascript&#8230;</strong></h2>
<p style="text-align: justify;">En général, je m&#8217;intéresse plus aux performances des serveurs que des clients au sens &laquo;&nbsp;navigateurs&nbsp;&raquo;. En réalité, la performance des clients est en générale très liée à celle des serveurs pour être plus précis. Mais le serveur ne peux pas toujours tout.</p>
<p style="text-align: justify;">Notamment les browsers encaissent plus ou moins bien le Javascript et surtout beaucoup de Javascript.</p>
<p style="text-align: justify;">Opera, Chrome, Firefox, Internet Explorer et leurs copains ont une tendance très nette à réagir différemment (je n&#8217;apprends rien aux développeurs Web) et surtout à réagir plus ou moins bien et plus ou moins vite en interprétation de Javascript. De plus, ces différences se cumulent avec des comportements très différents d&#8217;un browser à l&#8217;autre, notamment le nombre de requêtes concurrentes (nombres d&#8217;éléments de la page chargé en parallèle).</p>
<p style="text-align: justify;">Tous les sites récents utilisent énormément de Javascript et ont donc une belle tendance à charger la mule, surtout quand on a plusieurs onglets d&#8217;ouverts sur plusieurs sites, on a tout de suite des machine virtuelle javascript au sein des navigateurs qui se mettent à grossir.</p>
<p style="text-align: justify;">Ok, so what ? Qu&#8217;est ce que j&#8217;y peux me réponde les développeurs&#8230;</p>
<p style="text-align: justify;">Eh bien beaucoup de choses en fait. Déjà, un framework c&#8217;est bien mais ca n&#8217;empêche pas de réfléchir. Faire confiance aveuglément sans regarder le dessous des cartes, c&#8217;est ce qui mène au gâchis de ressources.</p>
<p style="text-align: justify;">Optimiser ces points (comme d&#8217;autres), c&#8217;est ce que j&#8217;appelle la &laquo;&nbsp;culture atari / amiga&nbsp;&raquo;.  En gros, à l&#8217;époque, les développeurs avaient des machines identiques, des machines avec des limites et on pensait à tirer le meilleur partie du Hardware, on optimisait son programme à la goutte prêt, on passait au plus proche du matériel pour faire des choses que les concepteurs de ces machines n&#8217;avaient même pas imaginé.</p>
<p style="text-align: justify;">De nos jours, on prend un framework, on instancie un objet et hop, derrière ca pédale mais c&#8217;est plus mon problème&#8230; Revenons à Javascript.</p>
<h2 style="text-align: justify;"><strong>Des soucis de tableaux !</strong></h2>
<p style="text-align: justify;">Il y a de nombreuses sources de maux dans Javascript, langage qui devient incontournable sur le Web depuis 5 ans. Mais lorsque les sites traitent de sujets plus complexes ou offres de nouveaux raffinement, ce qui était &laquo;&nbsp;une brique parmi d&#8217;autres&nbsp;&raquo; devient plus sensible.</p>
<p style="text-align: justify;">Commençons par un soucis simple de Javascript : les tableaux.</p>
<p style="text-align: justify;">Allouer un tableau en JS déclenche des mécanismes très différents d’un malloc en C. Allons y ! Sous IE, la logique de traitement est la suivante :</p>
<p style="text-align: justify;">var my_array = new Array();</p>
<p style="text-align: justify;">for (i = 0; i &lt; 100000; i ++)</p>
<p style="text-align: justify;">my_array[i] = i;</p>
<p style="text-align: justify;">1°) Je crée un objet array qui est une table de hashage.</p>
<p style="text-align: justify;">2°) Comme une table de hashage est un objet générique, je lui crée un attribue length (taille) et on le met à 0</p>
<p style="text-align: justify;">3°) La boucle fait, pour chaque valeur de i</p>
<ul style="text-align: justify;">
<li>Une conversion de i en string (chaine de caractère, en gros i= « i »)</li>
<li>Ajoute un clef de hash pour chaque couple « chaine i », i</li>
<li>Réajuste la valeur de length</li>
</ul>
<p style="text-align: justify;">OMG. Donc, rien que pour assigner une valeur au tableau, on a fait 3 opérations (dont deux totalement inutile si on a codé un jour en C).</p>
<p style="text-align: justify;">Pour compléter le tableau, les allocations réelles de mémoire ne sont pas continues car les tableaux sont gérés sous la forme de « sparse » array.</p>
<p style="text-align: justify;">C’est avantageux en terme d’usage réel de la RAM car les blocks vides ne sont pas alloués, par contre les allocations ne sont pas contigüe. Du coup, les accès à ces blocks de données ne se font pas à la suite et n’utilise pas certains mécanismes de prédiction des processeurs ou certains caches des OS. De plus les entrées du tableau ne sont pas indexées.</p>
<p style="text-align: justify;">Bon, maintenant, on a tout pour faire une usine à gaz de compétition !</p>
<p style="text-align: justify;">Pour résoudre ce premier point, sous IE 8, le « sparse array » est détecté comme étant dense ou non. En gros il est très peuplé ou non. Pour que l’heuristique de IE8 comprenne que c’est un « dense sparse array », il faut que ce tableau soit d’une taille explicite (en théorie mais un autre blog ne dénote pas de différence de perfs sur ce point) par contre, il faut en initialiser tous les éléments. Le défaut c’est que toute la RAM est allouée et le coté « sparse » disparait.</p>
<p style="text-align: justify;">Sur un gros PC ce n’est pas si dramatique mais sur un téléphone portable, ouch… Du coup, initialiser l’ensemble du tableau n’est pas toujours la bonne option. Un comportement optimal serait de détecter le navigateur et de lui proposer un Javascript optimisé pour le ratio Rapidité, consommation de CPU &amp; RAM, logique de traitement. Une sorte de librairie optimisée de gestion des tableaux, dépendante de la plateforme qui l’exécute.</p>
<p style="text-align: justify;">En termes d’impacts c’est non négligeable !</p>
<p style="text-align: justify;">Quelques très bon liens pour ceux que ca intéresse. Le premier blog a d’ailleurs de très bons papiers d’une manière générale !</p>
<p style="text-align: justify;"><a href="http://www.outofwhatbox.com/blog/2009/11/javascript-array-performance-initialize-to-optimize/">http://www.outofwhatbox.com/blog/2009/11/javascript-array-performance-initialize-to-optimize/</a></p>
<p style="text-align: justify;"><a href="http://www.outofwhatbox.com/blog/2009/12/javascript-array-performance-and-why-it-matters/">http://www.outofwhatbox.com/blog/2009/12/javascript-array-performance-and-why-it-matters/</a></p>
<p style="text-align: justify;"><a href="http://blogs.msdn.com/jscript/archive/2008/03/25/performance-optimization-of-arrays-part-i.aspx">http://blogs.msdn.com/jscript/archive/2008/03/25/performance-optimization-of-arrays-part-i.aspx</a></p>
<p style="text-align: justify;">
<h1 style="text-align: justify;"><strong>PHP et les performances : plantons le décor</strong></h1>
<p><BR></p>
<p style="text-align: justify;">Revenons à nos serveurs ! Dans une infrastructure Magento, ce qui pompe dur au niveau des performances, c’est PHP et de très loin.</p>
<p style="text-align: justify;">Il faut évidemment de la RAM pour accélérer les accès et traiter les données mais les appels PHP coutent très chers. Et c’est bien logique car le Web est coincé dans un incroyable paradoxe.</p>
<p style="text-align: justify;">Les langages interprétés (comme PHP) sont très adaptés à certains traitements mais d’une manière générale, pour tous les traitements répétitifs ou massifs, on les évite.</p>
<p style="text-align: justify;">L’idée c’est que dans la rapidité des langages, l’échelle est très claire :</p>
<h3 style="text-align: justify;"><span style="text-decoration: underline;">Les compilés :</span></h3>
<p style="text-align: justify;">Les langages ASM/C et C++ sont compilés et (donc) très rapides. On décrit le code et cela se transforme en Opcode directement interprétables et optimisables par le processeur. Tous les caches deviennent super efficaces (L1/L2/L3 du processeur notamment) et le programme traite les données au fil de l’eau et au fil du temps. Le programme se charge en mémoire, il ne s’arrête que quand on lui demande et peut sommeiller le temps d’attendre son prochain traitement.</p>
<p style="text-align: justify;">Assembleur : niveau processeur directement, très peu voir pas d’interprétation, vitesse maximale.</p>
<p style="text-align: justify;">C : Le code produit par un compilateur C est très proche de l’assembleur et donc extrêmement rapide. Pour autant cela reste un langage relativement évolué, contrairement à l’assembleur on a pas à tout écrire de zéro, des librairies existent, des includes, du code un peu évolué d’une manière générale.</p>
<p style="text-align: justify;">C++ : Un langage C évolué et Objet. On monte encore un peu dans les couches, on fait de l’objet et du fonctionnel, on en est plus à la douce barbarie redoutablement efficace de l’assembleur mais ca reste un code qui, une fois compilé, est redoutablement efficace.</p>
<p style="text-align: justify;">Très peu souples en typage ou en gestion de la mémoire, ces trois langages compilés, pour ne citer qu’eux, sont extrêmement rapides !</p>
<h3 style="text-align: justify;"><span style="text-decoration: underline;">La machines virtuelles :</span></h3>
<p style="text-align: justify;">Ce sont des programmes qui crée un environnement permettant d’exécuter d’autres programmes en leur sein. L’intérêt essentiel est de s’affranchir de la couche en dessous, en gros le programme devient portable partout. Si la VM existe pour l’environnement matériel cible, le programme tournera (presque) à l’identique sans rien redévelopper. L’inconvénient, comme toute forme de virtualisation, c’est que la VM consomme de la ressource pour créer cette couche d’abstraction, bilan ces langages ne sont pas toujours des foudres de guerre.</p>
<p style="text-align: justify;">Java et autres JVM</p>
<p style="text-align: justify;">Java est le plus connu des langages tournant dans une machine virtuelle, la JVM. C’est un bon langage, objet, évolué et indépendant du matériel mais il souffre de devoir être compilé tout en étant pas aussi rapide qu’un autre langage compilé.</p>
<p style="text-align: justify;">Les « interprétés » :</p>
<p style="text-align: justify;">Aïe. Perl, PHP et de nombreux copains à eux sont des langages dits « interprétés ». A chaque fois qu’il est lancé, le programme (test.php par exemple) est lu par un interpréteur externe (php par exemple), le fichier est parcouru, compilé à la volée quelque part, mais une fois finit, on repart de zéro. Le fichier programme à interpréter est donc lu à chaque fois et le programme qui le lit, l’interpréteur, est un programme qui est lui chargé à chaque exécution aussi.</p>
<p style="text-align: justify;">PHP :</p>
<p style="text-align: justify;">Un des plus célèbres. Zend au dessus est en fait composé de PHP objet évolué au sein d’un Framework, encore une couche d’abstraction. Donc si l’on compare avec nos précédents amis, Zend c’est le C++, Php le C sauf que tout cela est lu/chargé/parsé/interprété puis exécuté en continu. C’est un peu comme si on avait à se taper la compilation a chaque fois qu’on lance le programme… En fait l’image est très exacte puisque c’est quasiment exactement ce qui se passe. Bilan, les langages interprété c’est pratique, facile à maintenir et programmer, on s’affranchit de tous les aspects un peu rigoureux d’allocation mémoire ou de gestion des taches de bases mais le coût en terme de performances est énorme.</p>
<p style="text-align: justify;">PS : Javascript est un langage de scripting interprété tournant dans une machine virtuelle (navigateur)… Tout pour gagner J</p>
<h1 style="text-align: justify;"><strong>Vers un PHP compilé ?</strong></h1>
<p><BR></p>
<p style="text-align: justify;">Comme signalé plus haut, l’interprété c’est consommateur et pas adapté aux traitements récurrents. Maintenant si l’on considère une architecture d’hébergement Web, que se passe-t-il.</p>
<p style="text-align: justify;">Admettons que le site soit en Magento, on a un framework de deuxième niveau, qui repose sur un framework de premier niveau (Zend) qui repose sur un langage interprété objet (PHP5) qui repose sur un interpréteur (Php) qui lui-même est compilé et s’adresse en assembleur au processeur.</p>
<p style="text-align: justify;">Ajoutez un peu de virtualisation là-dessus et avant qu’une requête ne passe à travers tout ce maillage, vous avez perdu une quantité de puissance tout proprement hallucinante !</p>
<p style="text-align: justify;">En soit, aucun reproche au fait d’utiliser PHP ou sa syntaxe, par contre, soyons clairs l’approche est juste complètement aberrante. En fait si on essayait de faire pire, le seul moyen, ca serait de faire tourner l’interpréteur php dans une JVM…</p>
<p style="text-align: justify;">Et oui, ce n’est pas anodin mais bien dramatique. A chaque fichier PHP que vous chargez, l’interpréteur est lancé. A chaque fichier php de chargez, vous provoquez toute la cascade de compilation, d’accès disque, d’exécution. Quand un visiteur passe, il provoque donc des centaines de lancement du programme PHP qui va interpréter autant de fichiers… C’est une boucherie, une hémorragie de puissance pour finalement un problème très bête.</p>
<p style="text-align: justify;">Le problème ce n’est pas Magento, Zend ou les fichiers PHP en soit. Sortons de la barbarie de l’assembleur, vive l’objet et tout et tout, on développe plus vite, on réutilise du code, on capitalise des librairies ! C’est l’avancement logique, l’avenir, donc ca va continuer à se développer. Par contre, pourquoi on ne compile pas tout cela ?</p>
<p style="text-align: justify;">La charge CPU des serveurs serait juste divisée par un facteur 10 à vue de nez… C’est à ce point négligeable ? Plus clairement, sur un serveur, au lieu d’accueillir 20 000 personnes par jours par exemple, on en accueillerait 200 000. Avec le même serveur. L’approximation est un peu grossière mais pas outrancière non plus.</p>
<p style="text-align: justify;">Le Web, qui par essence provoque des milliers de lecture et interprétation de fichier de programme, utilise un système d’interprétation, ce qui est la pire façon de faire, ce qui est le plus consommateur possible. Voici le paradoxe.</p>
<p style="text-align: justify;">Si je me la faisais à la Yann Arthus-Bertrand, je redirais « alors pourquoi toi, homo sapiens sapiens, ne compile tu pas tes langages Web ?». Es-tu conscient des ressources gâchées par cette hérésie et de l’impact, de l’empreinte carbone, de cette approche incompréhensible ? Tu veux vraiment défoncer les puits de soleil ? Tu es un inconscient pathologique, un criminel notoire, un serial-gâcheur ? Ooops, je m’emporte&#8230; Yann (dont j’aime beaucoup le travail mais un peu moins la voix monocorde) n’irait pas jusque là !</p>
<p style="text-align: justify;">« Pourquoi ne compile t’on pas ? », bon ok, j’arrête de faire mon YAB…</p>
<p style="text-align: justify;">Je n’ai rien contre les développeurs, qui n’y peuvent pas grand-chose si ce n’est optimiser leur code (ca serait déjà un bon début pour certain ceci étant). Ce qui me froisse par contre, c’est que l’on a pas encore de solutions parfaitement mûres pour corriger ce point.</p>
<p style="text-align: justify;">Des soucis assez complexes de conception sont au rendez-vous pour passer du PHP de l’état interprétable à l’état compilé. Mais ne vous y trompez pas, le Graal est au bout de la route.</p>
<p style="text-align: justify;">Plusieurs initiatives sont en cour de développement par des gens talentueux que je ne peux qu’encourager dans cette voie : Roadsend et PHC (Php compiler mais qui paraît à l’arrêt) semblent être les leaders dans cette voie.</p>
<p style="text-align: justify;"><a href="http://www.phpcompiler.org/">http://www.phpcompiler.org/</a></p>
<p style="text-align: justify;"><a href="http://www.roadsend.com/home/index.php?pageID=compiler">http://www.roadsend.com/home/index.php?pageID=compiler</a></p>
<p style="text-align: justify;">L’autre approche possible serait un cache plus efficace, pas uniquement des opcodes comme APC mais bien des pages rendues, du résultat de l’interprétation PHP. C’est ce vers quoi se dirige Zend Server, c’est une bonne première transition mais le compilateur serait bien LA solution !</p>
<p style="text-align: justify;">
<h1><strong>En conclusion</strong></h1>
<p><BR></p>
<p style="text-align: justify;">Je dirais que PHP et surtout le modèle interprété qui va avec et Javascript et surtout l’implémentation qui en ait faite des les navigateurs autant que dans le code de certaines pages Web, sont deux problèmes.</p>
<p style="text-align: justify;">Ces deux axes de progression nous apporteraient un Web plus rapide, souple et agréable d’utilisation. Le réseau n’est plus réellement une limite, les processeurs sont suffisamment puissants alors deux cas sont possibles :</p>
<p style="text-align: justify;">-      Quelques personnes douées arrivent au bout de ces deux problèmes</p>
<p style="text-align: justify;">
<p style="text-align: justify;">-      Tout le monde se contente de ce qu’on a, on enterre la logique d’optimisation de l’époque atari &amp; amiga, on tue les phoques et la banquise en consommant inutilement des ressources informatiques précieuses. On compense par plus de puissance, plus de ressources consommées, plutôt que de mieux utiliser.</p>
<p style="text-align: justify;">
<p style="text-align: justify;">Un classique me direz-vous ?</p>
<p style="text-align: justify;">
]]></content:encoded>
			<wfw:commentRss>http://www.wikigento.com/optimisation-lampzendmagento/javascript-php-performances/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
	</channel>
</rss>

