<?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>Performance web &#187; parallélisation</title>
	<atom:link href="http://performance.survol.fr/avec/parallelisation/feed/" rel="self" type="application/rss+xml" />
	<link>http://performance.survol.fr</link>
	<description>Quelques mots pour des sites web rapides</description>
	<lastBuildDate>Fri, 18 Jun 2010 12:47:47 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Séparer en plusieurs domaines ?</title>
		<link>http://performance.survol.fr/2009/05/separer-en-plusieurs-domaines/</link>
		<comments>http://performance.survol.fr/2009/05/separer-en-plusieurs-domaines/#comments</comments>
		<pubDate>Thu, 28 May 2009 11:00:49 +0000</pubDate>
		<dc:creator>Éric</dc:creator>
				<category><![CDATA[Performance]]></category>
		<category><![CDATA[connexion]]></category>
		<category><![CDATA[dns]]></category>
		<category><![CDATA[domaine]]></category>
		<category><![CDATA[parallélisation]]></category>
		<category><![CDATA[téléchargement]]></category>

		<guid isPermaLink="false">http://performance.survol.fr/?p=485</guid>
		<description><![CDATA[L&#8217;année dernière je parlais du nombre de requêtes simultanées vers un même domaine. L&#8217;année dernière Internet Explorer 6 et 7 (2 requêtes simultanées) étaient fortement majoritaire, Firefox 3 (6 requêtes simultanées) était moins répandu que maintenant. L&#8217;étude de Yahoo! a &#8230; <a href="http://performance.survol.fr/2009/05/separer-en-plusieurs-domaines/">Continuer la lecture <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>L&#8217;année dernière je parlais du <a href="http://performance.survol.fr/2008/04/limitation-du-nombre-de-requetes/">nombre de requêtes simultanées vers un même domaine</a>. L&#8217;année dernière Internet Explorer 6 et 7 (2 requêtes simultanées) étaient fortement majoritaire, Firefox 3 (6 requêtes simultanées) était moins répandu que maintenant. <a href="http://yuiblog.com/blog/2007/04/11/performance-research-part-4/">L&#8217;étude de Yahoo!</a> a été faite il y a deux ans, sur des bases encore moins favorables.</p>
<p>Avec ces statistiques la recommandation était de répartir les téléchargements sur deux domaines, quatre maximum. On arrive donc à 4 ou 8 requêtes simultanées. Plus consomme inutilement du processeur et provoque un <a href="http://developer.yahoo.net/blog/archives/2007/07/high_performanc_7.html">surplus inutile de requêtes DNS</a>.<span id="more-485"></span></p>
<p>Ces différents domaines peuvent être des sous domaines ou pas, peuvent ou pas être des sites virtuels qui mènent en réalité à au même serveur physique, voire au même contenu. L&#8217;important est que le navigateur voit des URLs au domaine différent. Par contre ne faites jamais des liens aléatoirement vers un domaine ou un autre, vous perdriez tout le bénéfice du cache entre deux visite car les URLs changeraient à chaque fois.</p>
<h3>Une évolution des navigateurs</h3>
<p>Depuis deux ans le parc des navigateurs a évolué. Internet Explorer 8 fait une percée non négligeable. Les utilisateurs de Firefox utilisent quasiment tous la version 3 et représentent maintenant une proportion importante du trafic. Safari et Chrome font plus parler d&#8217;eux. On passe de 2 à 4 (Safari), 6 (Firefox 3, Internet Explorer 8, Chrome) voire 9 (dernière version d&#8217;Opera). Steve Souders a un bon résumé des <a href="http://stevesouders.com/ua/">capacités des différents navigateurs par rapport aux performances</a>, pour ceux que ça intéresse.</p>
<h3>A t&#8217;on encore besoin d&#8217;utiliser plusieurs domaines ?</h3>
<p>Clairement quatre domaines représentent alors entre 16 et 24 requêtes simultanées. C&#8217;est clairement trop ou inutile. Surtout avec l&#8217;apparition des terminaux mobiles et autres netbook avec une connexion wifi ou 3G pas excellente et une puissance processeur réduite.</p>
<p>L&#8217;étude nécessite d&#8217;être refaite avec un échantillon d&#8217;utilisateurs plus représentatif de la période actuelle. Si encore une moitié des utilisateurs reste avec 2 connexions simultanées, il devient contestable de leur faciliter la vie si ça pénalise la seconde moitié de la population.</p>
<p>Intuitivement je changerai bien la règle en &laquo;&nbsp;<strong>deux domaines, mais surtout pas plus</strong>&laquo;&nbsp;, tout en diminuant l&#8217;importance de ce critère. En fait le second domaine est nécessaire de toutes façons pour pouvoir utiliser un CDN et diminuer la latence sur les ressources statiques. Pour un site en ssl/https les domaines surnuméraires deviendront d&#8217;autant plus coûteux à cause de la poignée de main ssl et tout garder sur un seul domaine dans ce cas là ne devient pas forcément si négatif que cela.</p>
<p>Je vois peu de raisons de garder plus que ces deux domaines (le domaine principal avec le contenu dynamique et le CDN avec les ressources statiques). C&#8217;est d&#8217;autant plus vrai avec les publicités, qui vous feront utiliser encore un ou deux domaines différents quoi que vous fassiez.</p>
]]></content:encoded>
			<wfw:commentRss>http://performance.survol.fr/2009/05/separer-en-plusieurs-domaines/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Quel avenir ?</title>
		<link>http://performance.survol.fr/2008/12/quel-avenir/</link>
		<comments>http://performance.survol.fr/2008/12/quel-avenir/#comments</comments>
		<pubDate>Tue, 02 Dec 2008 11:00:34 +0000</pubDate>
		<dc:creator>Éric</dc:creator>
				<category><![CDATA[Performance]]></category>
		<category><![CDATA[compression]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[John Resig]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[Microsoft Internet Explorer]]></category>
		<category><![CDATA[mozilla]]></category>
		<category><![CDATA[opera]]></category>
		<category><![CDATA[parallélisation]]></category>
		<category><![CDATA[pipelining]]></category>
		<category><![CDATA[Steve Souders]]></category>
		<category><![CDATA[webkit]]></category>

		<guid isPermaLink="false">http://performance.survol.fr/?p=323</guid>
		<description><![CDATA[Vouloir optimiser le code et régler les performances, est-ce un sujet qui sera obsolète bientôt ? La question peut-être posée autrement : n&#8217;est-on pas en train de compenser les défauts des navigateurs dans quelques millions de sites avec des résultats &#8230; <a href="http://performance.survol.fr/2008/12/quel-avenir/">Continuer la lecture <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Vouloir optimiser le code et régler les performances, est-ce un sujet qui sera obsolète bientôt ?</p>
<p>La question peut-être posée autrement : n&#8217;est-on pas en train de compenser les défauts des navigateurs dans quelques millions de sites avec des résultats discutables au lieu de fixer les quelques navigateurs ?</p>
<h3>Sus au navigateur !</h3>
<p>Ma première réponse habituelle est de dire que si, nous sommes, pour bonne partie, en train de compenser les manques et les défauts de nos navigateurs. C&#8217;est le cas quand on parle d&#8217;agréger les contenus (au lieu d&#8217;utiliser le <a href="http://performance.survol.fr/2008/04/pipelining-enchainer-les-requetes-http/">HTTP pipelining</a>), quand on parle de <a href="http://performance.survol.fr/2008/04/javascript-a-sa-place/">déplacer les javascript en fin de document</a> (au lieu de <a href="http://performance.survol.fr/2008/08/javascript-non-bloquant/">laisser le navigateur les télécharger en parallèle</a>) ou quand on parle de <a href="http://performance.survol.fr/2008/04/limitation-du-nombre-de-requetes/">séparer les contenus statiques sur plusieurs domaines</a> (pour exploiter au mieux la configuration de nos navigateurs).</p>
<h3>Vive le navigateur !</h3>
<p>Heureusement il y a beaucoup d&#8217;activité actuellement chez les éditeurs logiciels. Opera, Apple/Webkit, Mozilla et même Microsoft font des efforts. La génération qui arrive va avoir des navigateurs avec beaucoup moins de goulots d&#8217;étranglement côté performances, et un ressenti de vitesse non atteint jusque là : Les javascript vont enfin pouvoir se télécharger en parallèle et ne plus bloquer le rendu, on ouvre plus de requêtes simultanées par serveur, et on tente quelques optimisations.</p>
<p>C&#8217;est Steve Souders qui nous propose <a href="http://stevesouders.com/ua/">un petit tableau récapitulatif sur les possibilités de cette nouvelle génération de navigateurs</a> (que <a href="http://ejohn.org/blog/browser-page-load-performance">John Resig commente</a>). Tout n&#8217;est pas parfait mais vous noterez intuitivement une bonne dose de vert pour Microsoft Internet Explorer 8, Minefield 3.1 (qui est la version de Firefox en développement), et WebKit 4. Les cases faisant la différence entre ces trois là sont liées aux redirections et au prechargement, ce sont certainement les colonnes les moins importantes de la grille. Opera reste de côté tant qu&#8217;il ne permet pas de paralléliser les scripts, mais il y a tout lieu de penser que cela va s&#8217;arranger.</p>
<h3>Agissons maintenant</h3>
<p>Tout va bien, arrêtons tout parce que ça va être corrigé sur les navigateurs ? Surtout pas ! Tout simplement parce que vos utilisateurs et votre site ne peuvent pas attendre les multiples années nécessaires à ce que le parc des navigateurs soit mis à jour.</p>
<p>Bref, nous n&#8217;avons pas le choix. Le visiteur se moque de savoir que c&#8217;est la faute du navigateur, qu&#8217;un plus récent est en préparation, ou même qu&#8217;un plus récent est disponible en téléchargement. Lui voit que votre site est lent, agaçant, et peut être qu&#8217;en allant chez le concurrent ça sera mieux &#8211; à navigateur égal.</p>
<p>En attendant que toutes les versions actuelles des navigateurs soient remplacées, vous devez agir, quitte à agir en pompier pour corriger les défaillances de ces derniers.</p>
<h3>Surtout que c&#8217;est un peu notre faute</h3>
<p>Mais n&#8217;oubliez pas, derrière cette grille il y a encore beaucoup de choses qui sont de la responsabilité de l&#8217;intégrateur web ou de l&#8217;administrateur web. Je parle de cache, d&#8217;agrégation de contenu, de compression http, d&#8217;images en sprites, d&#8217;optimisations javascript, ou simplement d&#8217;ordonnancement des composants.</p>
<p>Ne croyez pas que même avec ces superbes moteurs de navigateur qui arrivent, la performance deviendra un sujet obsolète.</p>
]]></content:encoded>
			<wfw:commentRss>http://performance.survol.fr/2008/12/quel-avenir/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Javascript en ligne</title>
		<link>http://performance.survol.fr/2008/08/javascript-en-ligne/</link>
		<comments>http://performance.survol.fr/2008/08/javascript-en-ligne/#comments</comments>
		<pubDate>Wed, 06 Aug 2008 10:00:36 +0000</pubDate>
		<dc:creator>Éric</dc:creator>
				<category><![CDATA[Performance]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[feuille de style]]></category>
		<category><![CDATA[inline]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[parallélisation]]></category>
		<category><![CDATA[Steve Souders]]></category>
		<category><![CDATA[velocity]]></category>

		<guid isPermaLink="false">http://performance.survol.fr/?p=70</guid>
		<description><![CDATA[Je fais suite au précédent billet sur la présentation de Steve Souders aux conférences Velocity 2008. Tout à la fin il nous donne une seconde information sur le javascript inline, et ceci est une nouveauté pour moi. La situation de &#8230; <a href="http://performance.survol.fr/2008/08/javascript-en-ligne/">Continuer la lecture <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Je fais suite au précédent billet sur <a href="http://en.oreilly.com/velocity2008/public/schedule/detail/3621">la présentation de Steve Souders aux conférences Velocity 2008</a>. Tout à la fin il nous donne une seconde information sur le javascript inline, et ceci est une nouveauté pour moi.</p>
<p>La situation de base : Firefox bloque tous les nouveaux téléchargements quand il récupère une feuille de style. Une fois n&#8217;est pas coutume c&#8217;est Internet Explorer qui est le plus efficace, car il permet de paralléliser tous ces téléchargements.</p>
<p>Enfin presque.<span id="more-70"></span>C&#8217;est là qu&#8217;est la découverte pour moi : Si un javascript en ligne est situé en dessous de la feuille de style, alors Internet Explorer imite le mauvais comportement de Firefox et bloque les téléchargements le temps de récupérer la feuille de style entièrement (<a href="http://stevesouders.com/cuzillion/?ex=10021">à teste</a>r sur <a href="http://performance.survol.fr/2008/04/tester-avec-le-cuzillon/">Cuzillon</a>).</p>
<p>Dommage non ?</p>
<p>La solution simple est de remettre votre javascript en ligne au dessus de la feuille de style, ou de le mettre dans un fichier externe avec une des <a href="http://performance.survol.fr/2008/08/javascript-non-bloquant/">techniques de chargement</a> vues précédemment.</p>
]]></content:encoded>
			<wfw:commentRss>http://performance.survol.fr/2008/08/javascript-en-ligne/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Javascript non bloquant</title>
		<link>http://performance.survol.fr/2008/08/javascript-non-bloquant/</link>
		<comments>http://performance.survol.fr/2008/08/javascript-non-bloquant/#comments</comments>
		<pubDate>Mon, 04 Aug 2008 10:00:45 +0000</pubDate>
		<dc:creator>Éric</dc:creator>
				<category><![CDATA[Performance]]></category>
		<category><![CDATA[IE8 What's Coming]]></category>
		<category><![CDATA[Internet Explorer]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[parallélisation]]></category>
		<category><![CDATA[Steve Souders]]></category>
		<category><![CDATA[Stoyan Stefanov]]></category>
		<category><![CDATA[téléchargement]]></category>
		<category><![CDATA[velocity]]></category>

		<guid isPermaLink="false">http://performance.survol.fr/?p=63</guid>
		<description><![CDATA[Je vous l&#8217;avais dit, une balise &#60;script&#62; bloque le rendu et les nouveaux téléchargements dans le navigateur le temps que le javascript soit complètement téléchargé et exécuté. Une des solutions c&#8217;est de reléguer cette balise à la fin du document. &#8230; <a href="http://performance.survol.fr/2008/08/javascript-non-bloquant/">Continuer la lecture <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Je vous l&#8217;avais dit, <a href="http://performance.survol.fr/2008/04/javascript-a-sa-place/">une balise <code>&lt;script&gt;</code> bloque le rendu et les nouveaux téléchargements</a> dans le navigateur le temps que le javascript soit complètement téléchargé et exécuté. Une des solutions c&#8217;est de reléguer cette balise à la fin du document.</p>
<p>Il y a des fois où ce n&#8217;est pas idéal et c&#8217;est Steve Souders qui étudie les solutions dans <a href="http://en.oreilly.com/velocity2008/public/schedule/detail/3621">sa présentation aux conférences Velocity 2008</a>. <span id="more-63"></span>Quelques cas en vrac :</p>
<ul>
<li>Le Javascript est prioritaire, il doit être téléchargé et exécuté le plus tôt possible, mais pas au prix d&#8217;un blocage de tout le reste ;</li>
<li>Il n&#8217;est pas possible déplacer l&#8217;insertion de la balise à la fin du document, le système ne le permettant pas ;</li>
<li>Vous ne voulez pas montrer à l&#8217;utilisateur que la page est toujours en train de se charger (logo et barre de statut) ;</li>
<li>Vous ne voulez pas que l&#8217;événement onload de la page attende le téléchargement et l&#8217;exécution du javascript.</li>
</ul>
<h3>Ne pas bloquer le rendu</h3>
<p>Pour résumer les solutions intéressantes abordées par Steve Souders :</p>
<h5>Passer par l&#8217;<acronym title="interface de programmation">API</acronym> <acronym title="document object model">DOM</acronym></h5>
<p>La première solution est d&#8217;insérer le javascript via la création d&#8217;un noeud DOM. Le script ne bloque alors plus les nouveaux téléchargements. Le problème principal est que certains navigateur délaient l&#8217;événement onload tandis que d&#8217;autres l&#8217;exécuteront avant la fin du script. Cette différence peut rendre la gestion de la page un peu difficile</p>
<pre>var se = document.createElement('script');
se.src = 'http://example.org/test.js';
se.type = 'text/javascript' ;
document.getElementsByTagName('head')[0].appendChild(se);</pre>
<h5>Passer par une iframe</h5>
<p>La seconde solution est d&#8217;insérer le javascript via une iframe. Le rendu et les nouveaux téléchargements ne sont pas bloqués, l&#8217;événement onload réagit de la même façon sur tous les navigateur. Le défaut est que l&#8217;iframe fait elle-même perdre un peu de temps au rendu et que pour réutiliser le contenu on est limité à avoir la page et le script sur le même domaine. Impossible donc d&#8217;utiliser un CDN sur un domaine tiers.</p>
<p>Cela demande de plus de réorganiser le script lui même. La page principale devra passer par <code>window.frames[x]</code> pour accéder aux fonctions du script, et le script devra lui passer par <code>parent.document</code> pour accéder au DOM de la page principale.</p>
<h5>Passer par XMLHttpRequest</h5>
<p>La solution qui peut paraitre magique c&#8217;est d&#8217;insérer le javascript via une requête XMLHttpRequest. Le script ne bloque ni les nouveaux téléchargements ni l&#8217;événement onload. Mieux le navigateur ne montre pas à l&#8217;utilisateur que la page continue à se charger. Cela peut amener l&#8217;utilisateur à avoir une meilleure impression de vitesse. Par contre on est ici aussi limité à un seul domaine pour la page HTML et le javascript, donc pas de CDN sur domaine tiers.</p>
<p>Je ne vous met pas de code, chacun a sa bibliothèque pour ça. Vous pouvez utiliser DOM ou <code>eval</code>, comme vous voulez.</p>
<h5>Passer par un script <code>DEFER</code></h5>
<p>Enfin, vous avez l&#8217;attribut <code>DEFER</code> que vous pouvez ajouter à une balise de script des plus classiqes. Là non plus le script ne bloque pas les nouveaux téléchargements &#8230; mais uniquement sous Internet Explorer.</p>
<h3>Préserver l&#8217;ordre d&#8217;exécution</h3>
<p>Tout ça donne déjà un bon aperçu mais tout n&#8217;est pas résolu. Dès que vous avez plusieurs javascript vous avez certainement des dépendances et l&#8217;ordre de chargement est important. Là ça se gâte. Vous oubliez la technique de l&#8217;iframe qui ne vous garantit rien.  </p>
<p>Si vous pouvez vous permettre d&#8217;avoir le javascript sur le même domaine que la page HTML, alors il va vous falloir gérer vous même un code dans XMLHttpRequest pour assurer l&#8217;ordre d&#8217;exécution.</p>
<div>Dans le cas contraire, Firefox préservera l&#8217;ordre d&#8217;exécution quand vous insérez vos scripts via DOM. Pas Internet Explorer. Il ne vous reste plus qu&#8217;à faire du cas par cas : charger via DOM pour Firefox, et utiliser une balise de script classique avec un attribut <code>DEFER</code> pour Internet Explorer.</div>
<p>L&#8217;écran 26 de la présentation donne une excellente grille de lecture de tout ça. Et les autres navigateurs ? motus et bouche cousue. Dans l&#8217;ensemble les comportements ont des chances d&#8217;être similaires à ceux de Firefox, mais c&#8217;est à tester. Il y a quelques liens vers <a href="http://performance.survol.fr/2008/04/tester-avec-le-cuzillon/">le Cuzillon</a> donc si certains veulent tester et donner les résultats Safari et Opera&#8230;</p>
<h3>Utiliser YUI</h3>
<p>L&#8217;équipe Yahoo! est toujours sur la brèche côté performance. Vous avez doc <a href="http://developer.yahoo.com/yui/examples/get/get-script-basic.html">un outil YUI pour charger dynamiquement scripts</a> et des feuilles de style en tenant compte des dépendances, sans bloquer le navigateur. Visiblement <a href="http://dannythorpe.com/2008/07/23/cross-browser-dynamic-javascript-loading/">tout n&#8217;est pas clair sur la situation de Safari</a>, il faudrait que je fouille un peu pour tirer ça au clair. D&#8217;ordinaire la politique est d&#8217;avoir un comportement stable sur tous <a href="http://developer.yahoo.com/yui/articles/gbs/">les navigateurs grade A</a>, dont Safari fait partie, donc j&#8217;ai bon espoir que si ce n&#8217;est pas déjà le cas, une solution finisse par être trouvée.</p>
<p>Pour le même prix l&#8217;outil YUI permet aussi de charger aussi les feuilles de style et éviter leur aspect bloquant sur Firefox.</p>
<p>Stoyan Stefanov <a href="http://yuiblog.com/blog/2008/07/22/non-blocking-scripts/">en parle</a> lui aussi, en détail.</p>
<h3>Et l&#8217;avenir ?</h3>
<p>Le bon côté c&#8217;est que les équipes <a href="http://webkit.org/blog/166/optimizing-page-loading-in-web-browser/">Webkit</a> et <a href="http://en.oreilly.com/velocity2008/public/schedule/detail/3290">IE8</a> ont dans leurs cartons la possibilité de charger les scripts sans bloquer le navigateur et en les exécutant dans l&#8217;ordre d&#8217;apparition dans la page.</p>
<p>Tout ceci est pour demain, et les navigateurs d&#8217;aujourd&#8217;hui ne sont pas amenés à disparaitre rapidement, mais au moins, à moyen terme, on pourra n&#8217;avoir de ralentissement que sur les anciens navigateurs. Reste juste à espérer que Firefox et Opera bougent aussi sur ce point, mais malheureusement je n&#8217;ai pas vu d&#8217;information dans ce sens.</p>
]]></content:encoded>
			<wfw:commentRss>http://performance.survol.fr/2008/08/javascript-non-bloquant/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Keep-alive et connexions persistantes</title>
		<link>http://performance.survol.fr/2008/04/keep-alive-et-connexions-persistantes/</link>
		<comments>http://performance.survol.fr/2008/04/keep-alive-et-connexions-persistantes/#comments</comments>
		<pubDate>Tue, 08 Apr 2008 11:10:47 +0000</pubDate>
		<dc:creator>Éric</dc:creator>
				<category><![CDATA[Performance]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[keep-alive]]></category>
		<category><![CDATA[parallélisation]]></category>
		<category><![CDATA[réseau]]></category>
		<category><![CDATA[téléchargement]]></category>

		<guid isPermaLink="false">http://performance.survol.fr/?p=16</guid>
		<description><![CDATA[La latence réseau a un impact très important sur les performances. Si les ressources sont zippées, que vos images sont correctement compressées, et que les fichiers textes sont minimisés, la latence peut devenir presque plus pénalisante que les téléchargements eux &#8230; <a href="http://performance.survol.fr/2008/04/keep-alive-et-connexions-persistantes/">Continuer la lecture <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>La latence réseau a un impact très important sur les performances. Si les ressources sont zippées, que vos images sont correctement compressées, et que les fichiers textes sont minimisés, la latence peut devenir presque plus pénalisante que les téléchargements eux même.<span id="more-15"></span></p>
<h3>Au niveau du contenu</h3>
<p>L&#8217;utilisation de javascript ou CSS concaténées et d&#8217;images en sprites diminuera l&#8217;impact de la latence par rapport au téléchargement lui même. L&#8217;utilisation d&#8217;un CDN diminuera la distance réseau entre vos serveurs et vos utilisateurs et réduira la latence elle-même.</p>
<p>Malheureusement vous aurez encore besoin d&#8217;au moins un fichier CSS, un fichier javascript, et probablement une bonne dizaine d&#8217;images au minimum. Cela fait douze requêtes. Avec un ping honnête de 40 ms, voilà une demi seconde qui part en fumée <a id="b16n1rev" href="#b16n1">[1]</a>. Inacceptable.</p>
<p><a id="b16n1" href="#b16n1rev">[1]</a> Et par respect pour <a href="http://performance.survol.fr/2008/03/impact-de-la-latence-reseau/#comment-5">l&#8217;intervention de Rik sur un précédent billet</a>, je signale que cette demi seconde est théorique, en pratique certains délais sont parallélisés donc ne délaieront pas d&#8217;autant le rendu de la page. L&#8217;impact reste cependant important, d&#8217;autant que votre site professionnel contient plus de douze ressources à télécharger non ?</p>
<h3>Au niveau du réseau</h3>
<p>Vos navigateurs ont heureusement deux mécanismes qui peuvent compenser notre demi seconde : keep-alive et pipelining. Nous parlerons ici du keep-alive, le pipelining sera pour demain.</p>
<p>Le keep-alive c&#8217;est le nom des connexions persistantes en HTTP. A partir de HTTP 1.1, par défaut votre serveur laisse la connexion ouverte après avoir répondu à une requête. Le navigateur peut alors relancer une nouvelle requête sur la même connexion, sans avoir à rétablir un nouvel échange TCP. C&#8217;est tout ça de gagné, et ce n&#8217;est pas négligeable.</p>
<h3>La problématique</h3>
<p>Les connexions persistantes sont un des réglages avec un fort impact sur les performances, sur lesquels on n&#8217;arrive pas à dégager un consensus.</p>
<p>La problématique est la suivante : une connexion persistante c&#8217;est une connexion qui reste ouverte pendant un certain temps &laquo;&nbsp;au cas où le navigateur ait encore des requêtes à faire&nbsp;&raquo;. Or une connexion ouverte a un impact négatif sur les performances du serveur. C&#8217;est un lien réseau ouvert et un processus avec son occupation mémoire. Un processus Apache avec PHP c&#8217;est généralement 5 à 10 Mo de mémoire vive. On ne peut pas en bloquer des centaines juste &laquo;&nbsp;pour attendre au cas où&nbsp;&raquo;. Si on surcharge le serveur, il répond plus lentement et au final les performances du client se dégradent aussi.</p>
<p>Une bonne pratique peut déjà être de réduire la durée valeur du keep-alive par défaut, c&#8217;est à dire la durée pendant laquelle le serveur garde la connexion ouverte en attente d&#8217;une nouvelle requête du navigateur. <a href="http://httpd.apache.org/docs/2.2/mod/core.html#keepalive">Par défaut Apache la règle à 5 secondes</a> (15 secondes sur les anciennes versions).</p>
<p>La difficulté est de trouver un bon équilibre entre cette fonctionnalité qui aide le client et les performances du serveur. Sachant que le gain pour le client est significatif mais pas critique, le compromis est trop souvent un refuge vers la situation la moins risquée &laquo;&nbsp;on désactive tout keep-alive sur le serveur&nbsp;&raquo;.</p>
<h3>Une recommandation rapide</h3>
<p>Une recommandation générique (je m&#8217;attends donc à ce que chacun me dise qu&#8217;il est dans une situation tierce) serait de désactiver le keep-alive sur les serveurs de contenu principaux, et de l&#8217;activer avec quelques secondes sur les CDN.</p>
<p>En considérant que vos images et fichiers tiers sont sur les CDN, vous ne devriez avoir qu&#8217;un seul téléchargement par page sur le serveur de contenu principal : la page HTML. Inutile d&#8217;activer le keep-alive et d&#8217;attendre d&#8217;autres requêtes si on sait qu&#8217;il y a des chances qu&#8217;il n&#8217;y en ait pas d&#8217;autres de si tôt. De plus ces serveurs gèrent des requêtes dynamiques, donc embarquent souvent des langages de script. Chaque processus prend beaucoup de mémoire, les connexions persistantes coûteraient cher.</p>
<p>Sur les CDN la problématique s&#8217;inverse. On y télécharge tous les fichiers tiers, probablement plus d&#8217;une dizaine par page quand le cache est vide. Garder la connexion ouverte est intéressant pour le client comme pour le serveur. Ce sont aussi des serveurs qui n&#8217;envoient que des fichiers statiques, l&#8217;empreinte mémoire et le coût d&#8217;un processus qui reste en attente sont probablement beaucoup plus faibles.</p>
<h3>Deux autres options</h3>
<p>Une autre option, plus simple, est de mettre un proxy inversé devant votre serveur web. C&#8217;est lui qui va garder les connexions persistantes avec les navigateurs, et les processus d&#8217;un proxy ne coûtent pas très chers.</p>
<p>Le serveur web Apache propose aussi un module expérimental : <a href="http://httpd.apache.org/docs/2.2/fr/mod/event.html">MPM Event</a>. Il permet d&#8217;utiliser un seul processus unique avec une file de connexions pour gérer les keep-alive, au lieu de bloquer un processus entier à chaque connexion persistante.</p>
<h3>Votre solution</h3>
<p>J&#8217;ai entendu dire tout et son contraire. Si vous avez fait des recherches ou simplement si vous avez testé plusieurs options, je suis curieux de connaitre vos conclusions et votre situation.</p>
<p>Pour l&#8217;instant j&#8217;ai surtout vu les trois solutions citées, dans le même ordre de préférence :</p>
<ul>
<li>Le plus souvent : on désactive tout, parce que le keep-alive est parfois plus négatif que positif, donc on joue la sécurité.</li>
<li>Pas de keep-alive sur les serveurs dynamiques, mais un keep-alive moyen sur les serveurs statiques.</li>
<li>Dans quelques cas un keep-alive assez long, mais géré par un proxy ou un serveur intermédiaire.</li>
</ul>
<p> </p>
]]></content:encoded>
			<wfw:commentRss>http://performance.survol.fr/2008/04/keep-alive-et-connexions-persistantes/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Limitation du nombre de requêtes</title>
		<link>http://performance.survol.fr/2008/04/limitation-du-nombre-de-requetes/</link>
		<comments>http://performance.survol.fr/2008/04/limitation-du-nombre-de-requetes/#comments</comments>
		<pubDate>Mon, 07 Apr 2008 15:57:24 +0000</pubDate>
		<dc:creator>Éric</dc:creator>
				<category><![CDATA[Performance]]></category>
		<category><![CDATA[connexion]]></category>
		<category><![CDATA[dns]]></category>
		<category><![CDATA[domaine]]></category>
		<category><![CDATA[parallélisation]]></category>
		<category><![CDATA[réseau]]></category>
		<category><![CDATA[téléchargement]]></category>

		<guid isPermaLink="false">http://performance.survol.fr/?p=14</guid>
		<description><![CDATA[Nos navigateurs sont performants, ils savent gérer plusieurs téléchargements en parallèle. Ca nous permet de palier les serveurs lents, et d&#8217;optimiser le réseau. Le temps qu&#8217;on se connecte sur un serveur, qu&#8217;on fasse une requête DNS, le réseau reste occupé &#8230; <a href="http://performance.survol.fr/2008/04/limitation-du-nombre-de-requetes/">Continuer la lecture <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Nos navigateurs sont performants, ils savent gérer plusieurs téléchargements en parallèle. Ca nous permet de palier les serveurs lents, et d&#8217;optimiser le réseau. Le temps qu&#8217;on se connecte sur un serveur, qu&#8217;on fasse une requête <acronym title="domain name server">DNS</acronym>, le réseau reste occupé avec d&#8217;autres téléchargements.</p>
<h3>Sans limite ?</h3>
<p>On ne peut pas non plus tout télécharger en parallèle. Si chaque contenu met une seconde à se télécharger, il est plus intéressant de les voir arriver un à un chaque seconde séquentiellement. En parallèle ils pourraient mettre tous dix secondes et on les verrait tous arriver simultanément à la fin.<span id="more-13"></span></p>
<p>Ce serait consommateur de ressources, sur le poste du client et sur le serveur. Nos dix requêtes simultanées prendraient dix processus sur le serveur pendant dix secondes au lieu d&#8217;un processus qui traite séquentiellement les requêtes. C&#8217;est dix fois plus de mémoire par exemple.</p>
<p>Enfin, le nombre optimum de connexions simultanées dépend de la bande passante disponible. Pas la peine de lancer vingt connexions simultanées. C&#8217;est plus de charge sur le serveur, plus de charge sur le client, un peu plus de r&amp;seau utilisé à cause de l&#8217;établissement des connexions, mais aucun gain.</p>
<p>Il faut une limite, tout en parallèle n&#8217;est intéressant pour personne.</p>
<h3>Quelle limite ?</h3>
<p>La <acronym title="request for comments">RFC</acronym> de HTTP 1.1 nous propose un maximum de deux requêtes persistantes simultanées par serveur. Les navigateurs jusqu&#8217;à récemment ont traduit ça en &laquo;&nbsp;deux requêtes persistantes simultanées par serveur qui répond en HTTP 1.1&#8243;.</p>
<ul>
<li>Firefox : 2 connexions simultanées par domaine par défaut, mais Firefox 3 prévoit d&#8217;en autoriser 6.</li>
<li>Internet Explorer : 2 connexions simultanées par domaine, sauf pour Internet Explorer 8 qui planifie d&#8217;en autoriser 6 aussi.</li>
<li>Opera 9 et Safari 3 autorisent chacun 4 connexions simultanées par domaine.</li>
</ul>
<p>Ces nombres sont augmentés si le serveur refuse les connexions persistantes, s&#8217;il répond en HTTP 1.0, ou si on passe par un proxy. Inversement, Microsoft Internet Explorer 8 tente de détecter si vous utilisez une connexion par modem RTC et revient alors à 2 requêtes simultanées par domaine pour ne pas saturer la ligne.</p>
<h3>Plusieurs domaines</h3>
<p>Jusqu&#8217;à récemment le conseil était d&#8217;étaler les ressources sur plusieurs domaines, de préférence 2. Cela permet de parallèliser les téléchargements puisque les limites sont &laquo;&nbsp;par domaine&nbsp;&raquo;. Au delà de 4 domaines <a href="http://yuiblog.com/blog/2007/04/11/performance-research-part-4/">l&#8217;équipe de performance Yahoo! a remarqué</a> qu&#8217;entre une trop grande parallélisation et <a href="http://developer.yahoo.net/blog/archives/2007/07/high_performanc_7.html">la multiplication des requêtes DNS</a>, l&#8217;effet commençait à devenir négatif.</p>
<p>La question mérite d&#8217;être reposée sachant que Firefox et Microsoft Internet Explorer vont tripler le nombre de requêtes. Nous retrouverons par défaut dans le cas &laquo;&nbsp;ressources étalées sur 3 domaines&nbsp;&raquo; sans rien avoir à faire, et ceux qui utilisaient déjà plusieurs domaines voient leur traffic simultané multiplié d&#8217;autant.</p>
<h3>La voie d&#8217;AOL</h3>
<p>AOL a lui choisit une politique particulière mais pas forcément mauvaise : son serveur répond en utilisant le protocole HTTP 1.0. Cela a des implications, comme l&#8217;impossibilités d&#8217;utiliser des Etags, mais ces derniers posent presque plus de problème qu&#8217;ils n&#8217;en résolvent.</p>
<p>Le HTTP 1.0 leur suffit. Ils profitent alors automatiquement de plus de connexions simultanées de la part des navigateurs sans avoir à multiplier les domaines et les requêtes DNS. Ils n&#8217;auront du coup aucun problème du au changement de configuration par défaut des navigateurs : ils étaient déjà dans une configuration avec beaucoup de requêtes simultanées.</p>
<h3>La recommandation</h3>
<p>En attendant des mesures de performances plus concrètes prenant en compte les configuration des nouveaux navigateurs, garder la recommandation de l&#8217;équipe de performance Yahoo! est probablement le plus sage : étaler vos ressources sur deux domaines différents.</p>
<p>Un seul domaine, même en HTTP 1.0 comme AOL, ne vous permet pas d&#8217;utiliser un <acronym title="content delivery network">CDN</acronym> pour diminuer la latence réseau. Plus de deux domaines risque de surcharger vos utilisateurs avec plus de connexions simultanées qu&#8217;il n&#8217;est bénéfique.</p>
<p>Le cadeau bonus c&#8217;est qu&#8217;en séparant les ressources statiques et dynamiques sur deux domaines, vous pouvez avoir une optimisation plus simple des ressources statiques : CDN, pas de cookie (c&#8217;est ça de gagné en traffic réseau), et entêtes d&#8217;expiration configurées globalement sur tout le domaine ; et une optimisation différente pour les ressources dynamiques : pas de keep-alive et entête imposant la revalidation des contenus pour éviter le cache.</p>
]]></content:encoded>
			<wfw:commentRss>http://performance.survol.fr/2008/04/limitation-du-nombre-de-requetes/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Javascript à sa place</title>
		<link>http://performance.survol.fr/2008/04/javascript-a-sa-place/</link>
		<comments>http://performance.survol.fr/2008/04/javascript-a-sa-place/#comments</comments>
		<pubDate>Tue, 01 Apr 2008 22:12:58 +0000</pubDate>
		<dc:creator>Éric</dc:creator>
				<category><![CDATA[Performance]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[parallélisation]]></category>
		<category><![CDATA[réseau]]></category>
		<category><![CDATA[téléchargement]]></category>

		<guid isPermaLink="false">http://performance.survol.fr/?p=12</guid>
		<description><![CDATA[Chaque fois que je parle de reléguer les codes javascript en fin de page, je vois une moue sur le visage de mon interlocuteur. Mettre le javascript dans le &#60;body&#62; du document, et encore plus à la fin de celui-ci, &#8230; <a href="http://performance.survol.fr/2008/04/javascript-a-sa-place/">Continuer la lecture <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Chaque fois que je parle de reléguer les codes javascript en fin de page, je vois une moue sur le visage de mon interlocuteur. Mettre le javascript dans le <code>&lt;body&gt;</code> du document, et encore plus à la fin de celui-ci, et souvent préjugé comme une pratique &laquo;&nbsp;sale&nbsp;&raquo;. Laissez moi vous convaincre du contraire.<span id="more-10"></span></p>
<h3>Un javascript pas sans conséquences</h3>
<p>Le code javascript est exécuté par nos navigateurs dès qu&#8217;il est lu et téléchargé. Il peut modifier le flux de contenu courant (principalement avec <code>document.write</code>) et donc modifier totalement l&#8217;interprétation du reste de la page. Imaginez par exemple que votre script insère <code>&lt;</code> juste devant <code>div&gt;</code>.</p>
<p>Le résultat ne peut pas être prévu à l&#8217;avance ni vraiment effectué après coup. Si <code>div&gt;</code> est déjà analysé le navigateur, l&#8217;ajout d&#8217;un chevron ouvrant ne pourrait plus transformer facilement ce texte en noeud DOM, puis changer toute la hiérarchie de noeuds DOM pour la brancher sur notre nouveau <code>&lt;div&gt;</code>. C&#8217;est trop tard.</p>
<h3>Stoppez tout !</h3>
<p>À cause de cela, le navigateur considère un script comme une ressource exclusive. Quand il rencontre une balise <code>&lt;script&gt;</code>, le reste de la page est mis en attente et l&#8217;analyse est stoppée le temps d&#8217;exécuter le script. L&#8217;interprétation du reste de la page reprendra quand le script sera téléchargé et que son exécution sera finie. Si le reste de votre page contient des images ou des composants externes, leur téléchargement sera retardé d&#8217;autant.</p>
<p>En insérant votre code javascript dans la balise <code>&lt;head&gt;</code>, ou en haut de votre document html, vous bloquez l&#8217;accès à la page. Pour un script de 50 ko, sur un débit réel de 2 mb/s et une latence de 40 ms, nous voilà à près de 250 ms auxquels il faudra encore ajouter le temps d&#8217;exécution du script. Votre navigateur vient d&#8217;arrêter tout l&#8217;analyse et le rendu de la page pendant un quart de seconde, pour un script de taille modeste. Imaginez si vous en avez plusieurs, ou qu&#8217;ils prennent un peu de temps à s&#8217;exécuter.</p>
<h3>Quelle est votre priorité ?</h3>
<p>Votre priorité c&#8217;est quoi ? la page elle-même et son contenu, ou vos ajouts javascript ? Si votre page est illisible sans javascript vous avez déjà définitivement un problème à la base, et il vous faut le corriger. Si votre javascript n&#8217;est qu&#8217;un ajout pour apporter un plus à l&#8217;utilisateur alors ne devrait-on pas privilégier l&#8217;affichage du contenu plutot que l&#8217;exécution du bonus javascript ?</p>
<p>Permettre d&#8217;insérer le code javascript à la fin du document, juste avant le <code>&lt;/body&gt;</code>, c&#8217;est permettre à l&#8217;utilisateur de charger la page et d&#8217;initier tous les téléchargements nécessaires avant de bloquer le navigateur sur ce javascript. Cela prendra toujours un quart de seconde, mais pendant ce temps le visiteur voit la page chargée. 250 ms ce n&#8217;est rien mais c&#8217;est ça qui fait la différence entre une page qui apparait rapidement et une page qui met du temps à se charger.</p>
<h3>Le cadeau bonus</h3>
<p>Le point bonus c&#8217;est qu&#8217;à ce moment là vous savez que toute la page est analysée. Vous pouvez interagir avec tout votre DOM sans avoir à attendre le chargement complet de tous les composants ou à mettre en place des systèmes plus ou moins brillants pour détecter la fin de chargement de l&#8217;arbre DOM. Fini les ajouts d&#8217;événements et les bidouilles pour implémenter le <code>DomContentLoaded</code> en javascript.</p>
<p>Reste à savoir pourquoi vous trouvez ça &laquo;&nbsp;sale&nbsp;&raquo; de mettre le code javascript en fin du <code>&lt;body&gt;</code>. C&#8217;est tout à fait prévu et accepté dans les spécifications HTML, cela donne des résultats concrets et importants au niveau performance, et ça rend même votre code plus simple. Le seul argument objectif que je peux concevoir c&#8217;est si vous avez deux rendus différents pour la page : avec et sans javascript. Mais il y a une astuce plus que simple pour ceci, ce sera l&#8217;occasion d&#8217;un autre billet.</p>
<h3>Safari</h3>
<p>Il est intéressant de noter que les développeurs de Safari <a href="http://webkit.org/blog/166/optimizing-page-loading-in-web-browser/">ont trouvé une solution partielle</a> à ce problème dans leur dernière version de développement. Quand un script est exécuté, le reste de la page est envoyé à un second moteur d&#8217;analyse, annexe. Ce dernier se contente de repérer les ressources à télécharger par la suite et lance le téléchargement en parallèle. Leur moteur privilégie aussi les scripts quand plusieurs téléchargements sont en file d&#8217;attente.</p>
<p>Cela ne résout pas l&#8217;affichage qui reste bloqué en attendant le script, par contre on évite beaucoup de problème de latence réseau et on améliore la parallélisation des téléchargements. Au final, on peut s&#8217;attendre à un gain de performance significatif sur les pages avec plusieurs composants javascript. chargés en haut de page.</p>
]]></content:encoded>
			<wfw:commentRss>http://performance.survol.fr/2008/04/javascript-a-sa-place/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>
