<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2frenchfull.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>BrainCracking</title>
	
	<link>http://braincracking.org</link>
	<description>HTML5, Performances Web et les technos du Web, par Jean-pierre VINCENT</description>
	<lastBuildDate>Wed, 30 Jan 2013 10:15:00 +0000</lastBuildDate>
	<language>fr-FR</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/braincracking" /><feedburner:info uri="braincracking" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/2.0/</creativeCommons:license><feedburner:emailServiceId>braincracking</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><feedburner:feedFlare href="http://add.my.yahoo.com/content?lg=fr&amp;url=http%3A%2F%2Ffeeds.feedburner.com%2Fbraincracking" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/bn/intatm_fr_1.gif">Subscribe with Mon Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fbraincracking" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href="http://www.bloglines.com/sub/http://feeds.feedburner.com/braincracking" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fbraincracking" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fbraincracking" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fbraincracking" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><feedburner:feedFlare href="http://www.plusmo.com/add?url=http%3A%2F%2Ffeeds.feedburner.com%2Fbraincracking" src="http://plusmo.com/res/graphics/fbplusmo.gif">Subscribe with Plusmo</feedburner:feedFlare><feedburner:feedFlare href="http://www.thefreedictionary.com/_/hp/AddRSS.aspx?http%3A%2F%2Ffeeds.feedburner.com%2Fbraincracking" src="http://img.tfd.com/hp/addToTheFreeDictionary.gif">Subscribe with The Free Dictionary</feedburner:feedFlare><feedburner:feedFlare href="http://www.bitty.com/manual/?contenttype=rssfeed&amp;contentvalue=http%3A%2F%2Ffeeds.feedburner.com%2Fbraincracking" src="http://www.bitty.com/img/bittychicklet_91x17.gif">Subscribe with Bitty Browser</feedburner:feedFlare><feedburner:feedFlare href="http://www.live.com/?add=http%3A%2F%2Ffeeds.feedburner.com%2Fbraincracking" src="http://tkfiles.storage.msn.com/x1piYkpqHC_35nIp1gLE68-wvzLZO8iXl_JMledmJQXP-XTBOLfmQv4zhj4MhcWEJh_GtoBIiAl1Mjh-ndp9k47If7hTaFno0mxW9_i3p_5qQw">Subscribe with Live.com</feedburner:feedFlare><feedburner:feedFlare href="http://mix.excite.eu/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fbraincracking" src="http://image.excite.co.uk/mix/addtomix.gif">Subscribe with Excite MIX</feedburner:feedFlare><feedburner:feedFlare href="http://www.webwag.com/wwgthis.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fbraincracking" src="http://www.webwag.com/images/wwgthis.gif">Subscribe with Webwag</feedburner:feedFlare><feedburner:feedFlare href="http://www.podcastready.com/oneclick_bookmark.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fbraincracking" src="http://www.podcastready.com/images/podcastready_button.gif">Subscribe with Podcast Ready</feedburner:feedFlare><feedburner:feedFlare href="http://www.wikio.com/subscribe?url=http%3A%2F%2Ffeeds.feedburner.com%2Fbraincracking" src="http://www.wikio.com/shared/img/add2wikio.gif">Subscribe with Wikio</feedburner:feedFlare><feedburner:feedFlare href="http://www.dailyrotation.com/index.php?feed=http%3A%2F%2Ffeeds.feedburner.com%2Fbraincracking" src="http://www.dailyrotation.com/rss-dr2.gif">Subscribe with Daily Rotation</feedburner:feedFlare><item>
		<title>Quel est le débit moyen en France</title>
		<link>http://feedproxy.google.com/~r/braincracking/~3/b0IJEZjrElU/</link>
		<comments>http://braincracking.org/2012/11/13/quel-est-le-debit-moyen-en-france/#comments</comments>
		<pubDate>Tue, 13 Nov 2012 07:30:43 +0000</pubDate>
		<dc:creator>jpvincent</dc:creator>
				<category><![CDATA[Performances]]></category>

		<guid isPermaLink="false">http://braincracking.org/?p=1126</guid>
		<description><![CDATA[À quelle vitesse s’affiche un site ? La question est importante tant le confort d’utilisation et les revenus d’un site peuvent dépendre de cette réponse. Vous intégrez probablement déjà des pratiques visant à améliorer le rendu des pages et leur réactivité, et si vous êtes en phase d’industrialisation, vous faites peut-être du monitoring de la [...]]]></description>
			<content:encoded><![CDATA[<p>À quelle vitesse s’affiche un site ? La question est importante tant le confort d’utilisation et les revenus d’un site peuvent dépendre de cette réponse. Vous intégrez probablement déjà des pratiques visant à améliorer le rendu des pages et leur réactivité, et si vous êtes en phase d’industrialisation, vous faites peut-être du monitoring de la performance. Au moment de paramétrer votre solution, une question a dû vous poser problème : quelle est la connexion type en France ? Et pour les mobiles ?</p>
<p>Nous allons non seulement répondre à ces deux questions, mais en plus nous apercevoir qu’il y a une question plus pertinente à se poser.</p>
<h2>Pourquoi et comment calibrer ses test ?</h2>
<p>Les solutions de <em>monitoring</em> du marché testent les pages généralement sans vous dire avec quel navigateur (probablement des <em>Webkit headless</em>, pour accélérer les tests), et le font depuis des <em>datacenters</em> qui sont beaucoup trop proches des nœuds principaux du Web. Potentiellement, les sondes sont exécutées à partir de machines hébergées physiquement dans le même <em>datacenter</em> que votre hébergeur ou avec un <em>peering</em> privilégié avec le CDN.</p>
<p>Autant dire que les tests standard ne sont pas représentatifs de ce qu&rsquo;endurent vos utilisateurs et c&rsquo;est la raison pour laquelle on limite volontairement débit et latence, par exemple sur l&rsquo;indispensable <a href="http://www.webpagetest.org/">WebPageTest</a> ou chez certaines solutions payantes. WebPageTest a le mérite d&rsquo;être transparent car vous avez une liste de connexions pré-paramétrées cependant nous allons voir qu&rsquo;elles ne représentent pas du tout la France.</p>
<div id="attachment_1142" class="wp-caption alignnone" style="width: 465px"><a href="http://braincracking.org/wp-content/uploads/2012/10/paramètre-WPT-org.png"><img class="size-full wp-image-1142 " title="paramètre WPT org" src="http://braincracking.org/wp-content/uploads/2012/10/paramètre-WPT-org.png" alt="" width="455" height="140" /></a><p class="wp-caption-text">Paramètres par défaut de WebPageTest.org</p></div>
<p>Côté transit réseau, il y a essentiellement 4 données qui influencent l&rsquo;affichage d&rsquo;un site :</p>
<ul>
<li>la latence ou ping, qui est le temps d&rsquo;un aller / retour entre un navigateur et le serveur qui lui répond. Pour le <a href="http://httparchive.org/trends.php">site moyen</a>, en HTTP 1.1, basé sur TCP, c&rsquo;est <a href="http://performance.survol.fr/2008/03/impact-de-la-latence-reseau/">la mesure la plus importante</a>. C&rsquo;est aussi la plus difficile à obtenir.</li>
<li>le download ou bande passante descendante, qui reste importante pour récupérer de gros objets. On nous vend des ADSL à plus de 20Mb/s (<a href="http://adsl.sfr.fr/toutes-nos-offres/">1</a>, <a href="http://abonnez-vous.orange.fr/residentiel/accueil/accueil.aspx">2</a>, <a href="http://www.free.fr/adsl/internet.html">3</a> et des mobiles à 5Mb/s, qu&rsquo;en est il vraiment ?</li>
<li>l&rsquo;upload qui est rarement pertinent dans la webperf.</li>
<li>la perte de paquets : pratiquement inexistante sur des connexion filaires, mais omniprésent sur mobile. Là par contre impossible de trouver des chiffres, en supposant qu&rsquo;ils signifient quelque chose</li>
</ul>
<p>Idéalement, il faudrait récupérer ces métriques de vos propres utilisateurs, grâce à du <a href="http://yahoo.github.com/boomerang/doc/use-cases.html">Real User Monitoring</a> (RUM), mais la mise en œuvre est moins aisée que de récupérer les informations de sources externes, telle que nous allons le faire ici.</p>
<p>Si vous êtes pressé ou si vous me faîtes aveuglément confiance (et je vous comprends), vous pouvez sauter directement à <a href="#resume">&laquo;&nbsp;En résumé&nbsp;&raquo;</a></p>
<h2>à la pêche aux chiffres</h2>
<p>En cherchant <a href="http://delicious.com/braincracking">dans mes archives</a> et sur Google, je me suis rendu compte qu&rsquo;il existait très peu de rapports rendus publics. J&rsquo;en liste ici 6 en extrayant des données brutes. N&rsquo;hésitez pas à m&rsquo;en indiquer d&rsquo;autres ou à décortiquer plus avant les sources.</p>
<h3><a href="http://royal.pingdom.com/2010/11/12/real-connection-speeds-for-internet-users-across-the-world/">Etude Akamai / Pingdom de 2010</a></h3>
<p>Akamai est le leader mondial des CDNs, autant dire qu&rsquo;ils voient passer du traffic et ont une bonne idée de ce qui se fait à l&rsquo;échelle mondiale. L&rsquo;étude de cette année là comprend la répartition des débits en France.</p>
<ul>
<li>Débit moyen : 3,3 Mb/s</li>
<li>Répartition :
<ul>
<li>25 % moins de 2 Mb/s</li>
<li>60 % entre 2 et 5 Mb/s</li>
<li>15 % plus de 5 Mb/s</li>
</ul>
</li>
</ul>
<h3><a href="http://www.akamai.com/stateoftheinternet/">Akamai 2012 </a></h3>
<p>Chiffres plus récents, mais dont l&rsquo;échelle de répartition a changé.</p>
<ul>
<li>Débit moyen : 4,6Mb/s</li>
<li>Débit moyen des réseaux mobiles : 2,8Mb/s</li>
<li>Répartition :
<ul>
<li>0,1% moins de 256Kb/s</li>
<li>45% plus de 4Mb/s</li>
<li>4% plus de 10Mb/s</li>
</ul>
</li>
</ul>
<h3>DegroupTest, <a href="http://www.degrouptest.com/publications/6/barometre-debit-internet-s1-2012/1">2012</a> et <a href="http://www.degrouptest.com/publications/5/barometre-debit-internet-s2-2011/6">2011</a></h3>
<p>La population des utilisateurs de Degrouptest est probablement biaisée, car on a affaire à des gens qui au minimum s&rsquo;inquiètent de leur débit. Ce qui exclut ma mère et probablement la votre. Mais ils ont l&rsquo;avantage de mesurer le ping, et d&rsquo;isoler les extrêmes comme la fibre, le mobile et l&rsquo;outre-Mer.</p>
<ul>
<li>Débit moyen : 8,27 Mb/s (5,4Mb/s hors fibre )</li>
<li>Débit moyen des réseaux mobiles : 2.5Mbps (chiffres 2011)</li>
<li>Ping moyen : 80ms (86ms hors fibre)</li>
<li>Ping moyen réseaux mobiles : 200ms</li>
<li>Débit montant moyen : 1,3 Mb/s ( 641Kbp/s hors fibre)</li>
<li>Répartition :
<ul>
<li>13% à 27Mb/s de débit moyen</li>
<li>87% à 5,4Mb/s</li>
</ul>
</li>
<li>à noter :
<ul>
<li>Meilleur latence possible : Fibre Orange avec 19ms. Les opérateurs ADSL se situent entre 70ms (Free) et 100ms (SFR)</li>
<li>1s-1.5s de latence sur satellite</li>
<li>270ms de latence depuis l&rsquo;outre-mer, 3Mbps de débit moyen</li>
</ul>
</li>
</ul>
<p>A noter que le débit et la latence moyenne ont baissé entre 2011 et 2012. J&rsquo;imagine que leur public a du s&rsquo;élargir à des zones moins bien couvertes.</p>
<h3><a href="http://www.60millions-mag.com/actualites/archives/la_verite_sur_le_debit_des_connexions_internet">60 millions de consommateurs, 2012</a></h3>
<p>Leur testeur de débit a tourné pendant 1 an en 2011 et leur public est probablement plus proche du français moyen que DegroupTest. En plus on y quantifie les variations périodiques de débit.</p>
<ul>
<li>Débit moyen : 5.6Mb/s</li>
<li>Répartition :
<ul>
<li>11.8% moins de 1Mb/s</li>
<li>12.8% de 1 à 2Mb/s</li>
<li>31,8% de 2 à 5Mb/s</li>
<li>30% de 5 à 10Mb/s</li>
<li>12% plus de 10Mb/s</li>
</ul>
</li>
<li>A noter :
<ul>
<li>-20% de débit à 21h</li>
<li>-10% le dimanche</li>
</ul>
</li>
</ul>
<h3><a href="http://www.arcep.fr/fileadmin/reprise/observatoire/4-2011/obs-marches-t4-2011.pdf">Etude ARCEP</a></h3>
<p>De cette étude sur les chiffres d’affaire des FAI et opérateurs mobile, j’ai extrait les volumes de population pour confirmer ou requalifier les chiffres des autres :</p>
<ul>
<li>22 millions d&rsquo;abonnements ADSL et fibre</li>
<li>0,6 million d&rsquo;abonnement fibre / cable</li>
<li>0,3 million abonnés RTC</li>
<li>32 millions d&rsquo;abonnés mobile &laquo;&nbsp;data&nbsp;&raquo;</li>
<li>+80% de volume de data mobile par an</li>
</ul>
<h3><a href="http://www.cedexis.com/fr/country-reports/">Statistiques Cedexis</a></h3>
<p>Les statistiques de “l’aiguilleur du net” mesurent le temps d’aller-retour moyen entre un utilisateur de FAI et un CDN afin de choisir le meilleur. Les valeurs de latence y sont plus hautes qu’ailleurs car les CDN ne font pas que servir des fichiers statiques, il y a beaucoup d’intelligence lorsqu’une requête arrive chez eux. Je les prends car elles donnent une bonne idée de la vitesse avec laquelle les fichiers arrivent chez l’internaute qui visite des sites utilisant les CDN.</p>
<ul>
<li>118 ms de latence pour des fichiers hébergés sur Akamai (leader)</li>
<li>134 ms de latence pour des fichiers sur Amazon EC2 Europe</li>
</ul>
<p>Après les chiffres bruts, passons à l&rsquo;analyse.</p>
<h2>Quelle analyse ?</h2>
<p>Il faut bien se dire que l&rsquo;on compare des études avec des buts différents : mesurer l&rsquo;efficacité des CDNs, des FAI ou avoir un vision plus globale oriente les méthodologies. C&rsquo;est pour cela que j&rsquo;explicite ma réfléxion, pour que vous utilisiez les commentaires pour critiquer ma tentative de compréhension.</p>
<h3>Le débit moyen</h3>
<p>Les statistiques d&rsquo;abonnement de l&rsquo;ARCEP montrent 2,7% d&rsquo;abonnés fibres par rapport au nombre total d&rsquo;abonnement, alors que Degrouptest reçoit 13% de ses mesures depuis la fibre. Nous pouvons donc requalifier le débit moyen de Degrouptest : <strong>5,01Mb/s</strong> (97,3 % * 5,4 Mb/s + 2,7 % * 27,3 Mb/s = 5,01 Mb/s).<br />
Cette nouvelle moyenne se situe entre celle d’Akamai pour la France (4,6 Mb/s), et celle de 60 millions de consommateurs (5,6 Mb/s). Akamai ne détaille pas sa méthode mais on suppose qu’elle est plus représentative, car non volontaire. Elle ne mesure cependant que la connexion entre Akamai et un internaute et Cedexis nous indique qu’Akamai n’est pas le plus performant. Il faudrait donc légèrement remonter ce chiffre. D’un autre côté, 60 millions de consommateurs a fait son étude en 2011, et entre-temps DegroupTest semble indiquer une baisse de débit ADSL de 600 Ko/s. Il faudrait donc revoir leur moyenne à la baisse. Les chiffres convergent vers la valeur DegroupTest, que j’estime légèrement surestimée (population trop “aware”).</p>
<p>Pour arrondir, on peut donc <strong>situer un débit moyen à 4,8Mb/s</strong> sur ligne fixe. Concernant le débit mobile moyen, Akamai et Degrouptest ont à 30Kb/s près la même moyenne, on peut l&rsquo;arrondir à <strong>fixer à 2,5Mb/s</strong>.</p>
<h3>La latence</h3>
<p>On applique la correction des stats ARCEP sur les stats DegroupTest et on obtient cette valeur arrondie : <strong>85ms</strong>. Cependant en regardant les données Cedexis, on voit des temps de réponse bien supérieurs, de 110ms par exemple pour récupérer un statique sur un CDN populaire comme Akamai. Cela est assez cohérent avec le fait qu&rsquo;un CDN rajoute forcément un peu de latence (temps de routage supplémentaire, mise en cache, etc.) et que la population Degrouptest est surement un peu moins représentative que celle mesurée par Cedexis.</p>
<p>Concernant le ping sur mobile, on manque cruellement de données, la seule qu&rsquo;on ait trouvé pour la France est celle de Degrouptest de 200ms. Dans des études bien moins larges dans d&rsquo;autres pays, les chiffres varient de <a href="http://www.webperformancetoday.com/2012/04/02/mobile-versus-desktop-latency/">200ms</a> à <a href="http://www.webperformancetoday.com/2011/10/26/interesting-findings-3g-mobile-performance-is-up-to-10x-slower-than-throttled-broadband-service/">300ms</a>.</p>
<p>Pour la latence, nous nous fixons donc une moyenne arrondie de <strong>95ms sur ligne fixe</strong> et <strong>200ms sur mobile</strong>.</p>
<h3>Le cas du mobile</h3>
<p>Donc le débit moyen sur réseau mobile (2,5Mb/s) est plus élevé que 25% des ADSL de France. La latence est tout de même deux à trois fois plus élevée. Mais même en calibrant vos tests avec ces données et en supposant que vous les exécutiez depuis <a href="http://mobitest.akamai.com/m/index.cgi">un vrai mobile</a>, vous réalisez vite que quelque chose cloche : le ressenti utilisateur n&rsquo;est pas du tout le même. En fait il manque une dernière composante, assez rare en ADSL : <strong>la perte de paquets TCP</strong>. Constamment les connexions ouvertes entre votre téléphone et l&rsquo;antenne relai sont interrompues par des obstacles physiques, électro-magnétiques ou un changement d&rsquo;antenne. Je n&rsquo;ai pas trouvé d&rsquo;étude avec un taux moyen de perte de paquet, aussi c&rsquo;est un peu au pifomètre que j&rsquo;utilise la valeur 25%. à débattre.<br />
Il manque également le côté aléatoire de la connexion qui fait tout le charme des réseaux mobiles : parfois vous téléchargez une image en une demie seconde, parfois vous n&rsquo;arrivez pas à avoir un octet pendant plusieurs minutes.<br />
Exécutez régulièrement les applications <a href="http://speedtest.net/mobile.php">speedtest</a> ou Degroupest (<a href="http://links.fhsarl.com/pplipple">iOS</a>, <a href="http://links.fhsarl.com/applendroid">Android</a>) pour halluciner sur la variabilité des caractéristiques réseau.</p>
<div id="attachment_1137" class="wp-caption alignnone" style="width: 310px"><a href="http://braincracking.org/wp-content/uploads/2012/10/test-débit-mobile.png"><img class="size-medium wp-image-1137 " title="test débit mobile" src="http://braincracking.org/wp-content/uploads/2012/10/test-débit-mobile-300x258.png" alt="" width="300" height="258" /></a><p class="wp-caption-text">Test débit mobile</p></div>
<p>Sur quelques tests ci-dessus, sur 2 tests effectués à moins d&rsquo;une minute d&rsquo;intervalle et sans bouger, vous pouvez voir une différence de latence de 1 à 4. Vous pouvez également voir des tests qui vont de 14Kb/s à 9Mb/s, sans compter ceux qui n&rsquo;aboutissent pas.</p>
<p>Mais non seulement il n&rsquo;existe pas d&rsquo;étude sur les trous réseau (en supposant qu&rsquo;une telle étude puisse être représentative), mais en plus <strong>nous ne voulons pas introduire d&rsquo;aléa dans le cadre du monitoring</strong>, ou alors comment savoir si une alerte en est vraiment une ? Nous devons malheureusement choisir des mesures dégradées mais fixes.</p>
<h3><a name="resume"></a>En résumé</h3>
<table>
<caption>Les connexions moyennes françaises en 2012</caption>
<tbody>
<tr>
<th></th>
<th scope="col">Lignes Fixes</th>
<th scope="col">Réseau mobile</th>
</tr>
<tr>
<th scope="row">Débit descendant</th>
<td>4,8Mb/s</td>
<td>2,5Mb/s</td>
</tr>
<tr>
<th scope="row">Latence</th>
<td>95ms</td>
<td>200ms<br />
(+25% de perte de paquets)</td>
</tr>
</tbody>
</table>
<h3>Il n&rsquo;y a pas de connexion type</h3>
<p>Mon prof de stats me tirerait les oreilles si on s&rsquo;arrêtait là. En effet une moyenne seule est à peu près inutile sans <a href="http://fr.wikipedia.org/wiki/%C3%89cart_type">l&rsquo;écart-type</a> qui permet de juger de la représentativité de cette moyenne. En fait une moyenne est certes pratique à manipuler, et il est utile de surveiller son évolution, mais <strong>elle est particulièrement trompeuse</strong> si la répartition des mesures n&rsquo;est pas concentrée autour de la moyenne.<br />
Et justement les études d&rsquo;Akamai, de l&rsquo;ARCEP et de 60 millions de consommateurs montrent qu&rsquo;il y a <strong>de fortes disparités dans l&rsquo;équipement des utilisateurs</strong>.</p>
<ul>
<li>L&rsquo;ARCEP nous dit qu&rsquo;il reste 1,4% de gens en RTC (56Kb/s), soit à l&rsquo;échelle de la France 300 000 personnes. Dur de savoir si c&rsquo;est leur unique moyen d&rsquo;accéder au Web, mais c&rsquo;est un débit 500 fois inférieur aux mobiles ! Akamai signale également un faible taux de débit inférieurs à 256Kb/s</li>
<li>DegroupTest nous avertit sur le fait que depuis la France d&rsquo;outre-mer, on a du 250ms de ping en moyenne, l&rsquo;équivalent du mobile, et un débit 40% inférieur à la métropole</li>
<li>60 millions de consommateurs et Akamai montrent que <strong>50% des utilisateurs ont moins de 5Mb/s</strong>, avec une répartition qui a l&rsquo;air à peu près égale par tranche de 1Mb/s : 10% ont moins de 1Mb/s, <strong>20% moins de 2Mb/s</strong>, etc.</li>
<li>les tuyaux du Web français sont embouteillés le soir, avec une <strong>perte de 20% de débit entre 21h et 22h</strong>.</li>
</ul>
<div id="attachment_1144" class="wp-caption alignnone" style="width: 519px"><a href="http://braincracking.org/wp-content/uploads/2012/10/répartition-débits.png"><img class="size-full wp-image-1144" title="répartition débits" src="http://braincracking.org/wp-content/uploads/2012/10/répartition-débits.png" alt="" width="509" height="369" /></a><p class="wp-caption-text">Il n&rsquo;y a pas d&rsquo;ADSL type en France</p></div>
<p><strong>Nous nous sommes donc posés la mauvaise question</strong> : calibrer vos tests sur LA moyenne française est à peine moins trompeur que de mesurer depuis votre poste avec votre navigateur récent, sur votre réseau d’entreprise branché à la fibre (oui tout le monde le fait, et c’est MAL).</p>
<h2>Enfin : quelle stratégie de test ?</h2>
<p>Tous ces chiffres vont nous permettre de définir une vraie stratégie de test de la performance perçue. Cela commence par définir des objectifs de réactivité raisonnables en terme de confort d’utilisation, par exemple :</p>
<ul>
<li>afficher quelque chose avant 1 seconde (start render)</li>
<li>promesse / fonction principale de la page affichée avant 2 secondes</li>
<li>fonction principale interactive avant 5 secondes</li>
</ul>
<p>Note : les valeurs que j’indique ici sont un peu génériques, et sont à définir entre les équipes “produit” (marketing, ergonomie) et les équipes techniques (développeurs, sysadmins).<br />
Vous devez maintenant être cruel et déterminer quelle proportion d’utilisateurs n’aura pas droit à cette rapidité. C’est un peu rude dit comme ça, mais une page rapide pour “tout le monde” coûte très cher. Généralement on vise à satisfaire par exemple 80 % de la population.</p>
<p>Voici un petit tableau qui devrait vous aider à prendre vos décisions :</p>
<table>
<caption>Calibrage des tests pour ligne fixe</caption>
<tbody>
<tr>
<th scope="col">Un débit de <strong>X</strong> Mb/s</th>
<th scope="col">et une latence de <strong>Y</strong> ms</th>
<th scope="col">laissent de côté <strong>Z</strong> % des visiteurs</th>
</tr>
<tr>
<td>5.0Mb/s</td>
<td>95ms</td>
<td>50%</td>
</tr>
<tr>
<td>4.0Mb/s</td>
<td>100ms</td>
<td>40%</td>
</tr>
<tr>
<td>3.0Mb/s</td>
<td>110ms</td>
<td>30%</td>
</tr>
<tr>
<td>2.0Mb/s</td>
<td>120ms</td>
<td>20%</td>
</tr>
</tbody>
</table>
<p>Remarques :</p>
<ul>
<li>Les débits et pourcentages semblent joliment arrondis. C&rsquo;est de la chance.</li>
<li>Pour le ping, on n&rsquo;a aucune stat sur la répartition réelle, ce sont donc des suppositions personnelles que je vous invite à critiquer</li>
</ul>
<p>Pour le réseau mobile, on est bien embêté car on n’a aucune idée de la répartition ! On sait juste qu’elle est très volatile, ne serait-ce que pour le même utilisateur. Donc, soit on joue ça au doigt mouillé avec la certitude de se tromper, soit on utilise la moyenne qui est pratiquement un mensonge. Mmmm. Choix cornélien mais, à choisir, autant partir sur une valeur un tout petit peu objective, c’est-à-dire la moyenne constatée, et y rajouter de la perte de paquets.</p>
<p>Je mettrais donc ces 3 valeurs par ordre de priorité :</p>
<ol>
<li>3,0Mb/s avec une latence de 110ms pour représenter 70% de vos utilisateurs</li>
<li>2,5Mb/s avec une latence de 200ms et <strong>une perte de paquets de 25%</strong> pour l&rsquo;ensemble des utilisateurs de réseau mobile</li>
<li>4,80Mb/s avec une latence de 95ms pour &laquo;&nbsp;la moyenne&nbsp;&raquo; des connexion filaires</li>
</ol>
<p>La moyenne reste là surtout parce que c&rsquo;est un chiffre que tout le monde (croit) comprendre et pour comparer mobile et bureau.</p>
<p>Si vous avez une population particulière (outre-mer, visiteurs à 21 h, habitant une grande ville, professionnelle, très mobile, etc.), il va vous falloir fouiller dans les chiffres ci-dessus pour trouver ce qui se rapproche le plus de vos utilisateurs. Ou, bien sûr, monter votre propre monitoring des capacités de vos utilisateurs.</p>
<h2>Résultats</h2>
<p>Pour conclure, comparons les valeurs DSL par défaut de WebPageTest.org avec celles que nous avons déterminées pour représenter 70 % des français. J’ai lancé un test sur un site moyennement complexe, qui n’a pas (encore) été optimisé et qui fait partie des sites à forte audience de France : Pluzz.fr.</p>
<div id="attachment_1181" class="wp-caption alignnone" style="width: 1554px"><a href="http://braincracking.org/wp-content/uploads/2012/11/pluzz-comparaison-valeurs-defaut-et-custom.png"><img src="http://braincracking.org/wp-content/uploads/2012/11/pluzz-comparaison-valeurs-defaut-et-custom.png" alt="" title="pluzz-comparaison-valeurs-defaut-et-custom" width="1544" height="290" class="size-full wp-image-1181" /></a><p class="wp-caption-text">Comparaison valeurs par défaut et personnalisées</p></div>
<p>Pour plus de détails, voir <a href="http://www.webpagetest.org/video/compare.php?tests=121014_2994e714a56d3b251702fd9e2dcf43c0%2C121014_aa3557eec96550f644cc462b1d3647bb&#038;thumbSize=200&#038;ival=100&#038;end=visual">le détail du déroulé</a>. Avec les valeurs par défaut, ce site s’affiche en moins d’une seconde, donnant l’impression que l’optimisation n’est pas nécessaire. Avec nos valeurs plus réalistes prenant en compte 70 % de la population, le start render se situe à 1,4 seconde, confirmant le besoin d’entamer des travaux si l’on veut atteindre les objectifs de performance perçue.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/braincracking?a=b0IJEZjrElU:6a-0miJaQ0Y:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/braincracking?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=b0IJEZjrElU:6a-0miJaQ0Y:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/braincracking?i=b0IJEZjrElU:6a-0miJaQ0Y:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=b0IJEZjrElU:6a-0miJaQ0Y:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/braincracking?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=b0IJEZjrElU:6a-0miJaQ0Y:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/braincracking?i=b0IJEZjrElU:6a-0miJaQ0Y:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=b0IJEZjrElU:6a-0miJaQ0Y:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/braincracking?i=b0IJEZjrElU:6a-0miJaQ0Y:V_sGLiPBpWU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/braincracking/~4/b0IJEZjrElU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://braincracking.org/2012/11/13/quel-est-le-debit-moyen-en-france/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://braincracking.org/2012/11/13/quel-est-le-debit-moyen-en-france/</feedburner:origLink></item>
		<item>
		<title>Performance web mobile, chargement de page 2/2</title>
		<link>http://feedproxy.google.com/~r/braincracking/~3/RNxe7EgtV5k/</link>
		<comments>http://braincracking.org/2012/11/06/performance-web-mobile-chargement-de-page-22/#comments</comments>
		<pubDate>Tue, 06 Nov 2012 20:51:38 +0000</pubDate>
		<dc:creator>jpvincent</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Performances]]></category>

		<guid isPermaLink="false">http://braincracking.org/?p=1164</guid>
		<description><![CDATA[Reprioriser les optimisations On l’a vu dans le premier article, certaines techniques pourtant reconnues peuvent devenir contre-productives si l’on ne fait pas les tests nécessaires. Ne jetons cependant pas tout aux orties, voici les techniques que vous devrez maîtriser plus que jamais et pousser dans leurs extrêmes si vous voulez obtenir un résultat correct sur [...]]]></description>
			<content:encoded><![CDATA[<h1>Reprioriser les optimisations</h1>
<p>On l’a vu <a href="http://braincracking.org/?p=1156">dans le premier article</a>, certaines techniques pourtant reconnues peuvent devenir contre-productives si l’on ne fait pas les tests nécessaires. Ne jetons cependant pas tout aux orties, voici les techniques que vous devrez maîtriser plus que jamais et pousser dans leurs extrêmes si vous voulez obtenir un résultat correct sur mobile ; par ordre de priorité :</p>
<h2>1. Travailler le chemin critique</h2>
<p><strong>La notion de performance est plus un ressenti qu’une collection de chiffres</strong>. Lorsque vous devez retravailler une page pour un réseau mobile, demandez-vous ce que l’utilisateur est vraiment venu voir et dégagez le passage pour afficher au plus vite la zone ou la rendre fonctionnelle :</p>
<ul>
<li>pas (trop) de redirections, et surtout pas côté client ;</li>
<li>concaténation ou mise en ligne des CSS ;</li>
<li>un code HTML / CSS prêt à &laquo;&nbsp;marcher&nbsp;&raquo; sans JavaScript : pour un article, c’est facile, on affiche le texte (sans police de caractère, jamais) ; pour une vidéo, on peut utiliser HTML5 comme interface de lecture en attendant JavaScript. Si vous dépendez de JavaScript pour afficher la fonctionalité (un webmail par exemple), affichez au moins un indicateur de chargement ;</li>
<li>scripts asynchrones comme vu dans le premier article ;</li>
<li>JavaScript chargé et exécuté par ordre de priorité : on peut très bien imaginer de charger d’abord les fichiers JavaScript concaténés qui concernent la zone principale, puis un second pack de fichiers qui concernerait tout le reste de la page.</li>
</ul>
<h2>2. Minimiser le nombre de requêtes HTTP</h2>
<p>On l’a vu lors de l’exemple du <em>domain-sharding</em>, la première limite vient du réseau : le même mobile sur la même session de surf pourra passer d’un WiFi de bonne qualité à une absence complète de réseau. Vous ne pouvez jamais prévoir quand la latence va s’allonger jusqu’au <em>timeout</em> ou quand le débit passera en dessous de ce dont vous auriez besoin pour afficher une simple image. En supposant que vous serviez votre site classique sur mobile (1 Mo, 100 requêtes, 15 domaines… <a href="http://httparchive.org/trends.php">source http archive</a>), il va falloir faire baisser de manière drastique le nombre de requêtes pour minimiser les effets de latence ou de timeout et maximiser l’utilisation de la bande passante. Cet objectif est là pour durer et la plupart des techniques classiques utilisées jusqu’ici sont non seulement à investiguer, mais à pousser dans leurs extrêmes.</p>
<h3>La concaténation</h3>
<p>Il est plus que jamais temps de faire de vos CSS et JS des fichiers uniques ou presque. De base dans <a href="http://rubyonrails.org/">Ruby on Rails</a>, avec des plugins divers pour <a href="http://www.spip.net/">Spip</a> ou <a href="http://drupal.org/">Drupal</a>, avec <a href="https://github.com/widmogrod/zf2-assetic-module">Assetic</a> pour Zend 2, des dizaines de librairies pour d’autres projets PHP, avec <a href="http://sass-lang.com/">SASS</a> côté CSS et des outils comme <a href="http://yuilibrary.com/projects/yuicompressor/">YUI Compressor</a>.<br />
Il n’y a plus vraiment d’excuses pour ne pas gérer correctement vos JS et CSS, sauf peut être le coût de refactoring initial, mais il reste généralement négligeable par rapport aux bénéfices attendus.</p>
<p>À noter que les stratégies de concaténation vont varier en fonction de la taille de votre site : si il est relativement petit, mettez tous vos CSS dans une seule feuille ; si il est plus grand, mettez le CSS commun dans une première feuille et les CSS de chaque type de page dans une autre. Ne dépassez jamais 2 feuilles par page. En JavaScript, les stratégies sont plus variées du moment que vous utilisez l’asynchrone : un fichier unique pour tout le site si il est petit, un fichier par zone fonctionnelle sinon (avec chargement asynchrone).</p>
<h3>Les images</h3>
<p>Les images sont généralement petites et nombreuses, c’est donc votre seconde cible après le CSS. Vous avez forcément déjà entendu parler du <a href="http://www.alsacreations.com/tuto/lire/1068-sprites-css-background-position.html">spriting</a> ; sur mobile, vous pouvez aller encore plus loin avec les caractères unicode : lorsque vous avez beaucoup d’icônes, essayez de voir si vous pouvez en réutiliser (♻) qui viendraient directement des polices du système !<br />
Attention à la compatibilité navigateur ET système d’exploitation. Pour les mobiles, c’est généralement bon ; pour IE sur XP, vous n’aurez qu’un choix limité.</p>
<p>Encodage des images : visez le zéro requête en encodant vos images en texte directement dans le CSS, voire dans le HTML. C’est un peu fastidieux à faire à la main mais un simple script PHP suffit :</p>
<pre><code>print '&lt;img src="data:image/png;base64,'.base64_encode(file_get_contents('/path/to/image.png')).'" /&gt;';</code></pre>
<p>Qui vous donnera en sortie quelque chose de ce genre :</p>
<pre><code>
&lt;img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABO1BMVEX92RlCQj+7vLzvzSzmhgnXgybyz3uLj5T13mj99cDwrmWMfzXmyTz78bT1zUf++uX437bxzqzmpj/dlDdcVUbuxnjszDLq6uvqmS/43Hv99t+foaOMgl5tYDjsu1vfwT388NijlXr52Vn22Y3999Z2bmD34svhrFlQTD378ajuwWXThzH668PpsFbvw5zrtU2Vh03x0Y3MzMz73kr664qZmZnmnUblqm/7w1HokRbefBb//e324HL2z0TsuENYRC399s/343z46paYijr88s/z1KXvyIvspkzroTj81yL56cnajjLwxm9KSkLmqj1gVj+Xg2H3vkv+/tz35XL+3CD89cj45Lf88MSipab13FnvtGP224T45Yb78rr++uv3zij25Grz1Ub1yi7wxFztu2vYiTH95kfqs2v45csXvxkaAAAAAXRSTlMAQObYZgAAAMlJREFUaN5jYAACY0llQzafZFsGCAiJDvNSkJJSEEjR9wQLROvw86s4OISqxLkJgfhKYfz8/NZA4MBrnW4HFGBzkZKKAwlIxWpmCAMFRKVCQ1VUXFzCY52CpVKBAlpeKo4xUVFR7jGRJmreQAE+N2sbCRsbDhuWxCBzP5Cpcq5BHjYJCTaWnIKsYHs9dV25bIDAXY81CeIyT3WzwLQ0CyvteKhTGcQCFJ25Ve2ZGeBAJiLClN0fwWcwYBI3kpZFEuAR8WXUkGfACgC55CKssDjPhQAAAABJRU5ErkJggg==" /&gt;
</code></pre>
<p>Des frameworks complets comme SASS permettent de le faire dans le CSS. Vous pouvez utiliser cette technique à partir de IE8, et envisager <a href="http://www.phpied.com/the-proper-mhtml-syntax/">l’équivalent MHTML</a> pour IE7.</p>
<h3>Le nombre de domaines</h3>
<p>Le site moyen a entre 10 et 15 domaines à faire résoudre et il n’y a pas eu d’études sur l’utilisation du cache DNS sur mobile. Pratiquement invisible sur ordinateur de bureau, le coût de recherche DNS est peut être dix fois plus important sur mobile à cause de la latence. Chaque recherche de domaine va bloquer une file de téléchargement en attendant la réponse. Donc, soit vous sacrifiez trackers, publicité, widgets et autres sources externes, soit vous les dépriorisez fortement, tout simplement en les appelant après vos propres fichiers.</p>
<h3>Connexions permanentes</h3>
<p>Si vous avez une version dédiée mobile de votre site (pas de problématique de référencement, code spécifique), autant y aller à fond et utiliser une technologie très prometteuse pour contrer les effets de la latence : WebSocket. Pointez deux navigateurs <a href="http://html5demos.com/web-socket">cette page de démo</a>, et observez le peu de délai dans la transmission d&rsquo;une info d&rsquo;un navigateur à l&rsquo;autre, réseau mobile ou pas. Websocket ou d&rsquo;autres techniques de connexions permanentes peuvent être détournées : vous chargez en une seule requête une page initiale ne contenant que le strict nécessaire de CSS, de contenu et de JS, puis vous chargez tout le reste (images, CSS, JS, contenu) via cette connexion, que vous pouvez même réutiliser pour renvoyer des informations (AJAX, tracking…), sans payer le prix d&rsquo;ouverture de nouvelles connexions HTTP.<br />
Je n&rsquo;ai pas encore vu d&rsquo;équipe web déclarer avoir implémenter cela, mais ça ne saurait tarder. Au pire, patientez un peu, je vais coder une démo sur de vrais sites.</p>
<h2>3. Le cache et l’offline</h2>
<p>Comme avant, il va falloir que vous commenciez par maîtriser absolument toutes les URLs vers les statiques de votre site pour pouvoir les servir avec des caches agressifs, sur des domaines sans cookies. Ça c’est surtout pour les navigateurs de bureau car <a href="http://www.guypo.com/mobile/understanding-mobile-cache-sizes/">le cache des navigateurs mobile est une vraie calamité</a> en terme d’efficacité ! Il y a beaucoup trop de limites (nombre d’objets, taille maximale par objet, taille maximale par site et taille maximale pour tout le navigateur) pour espérer de vrais gains avec les comportements par défaut. Attention il ne faut pas les ignorer pour autant, si votre visiteur va d&rsquo;une page à l&rsquo;autre, il sentira la différence.</p>
<p>Les sites très efficaces en sont donc à utiliser HTML5 localStorage pour stocker des JS, des CSS et même des images (encodées en base64). C’est la technique choisie par LinkedIn mobile, Bing ou GMail, et elle demande un certain niveau de maîtrise de son application. Par exemple, imaginez-vous sur une page d’accueil : vous allez télécharger via XHR tous les objets dont vous avez ou aurez besoin, puis les stocker dans localStorage.</p>
<pre><code>var loader = new XMLHttpRequest();
loader.open("GET", "http://example.com/js/main.js");
loader.onload = function(e) {
    localStorage.setItem('main.js', e.response);
}
loader.send();</code></pre>
<p>Ensuite, au moment ou vous en avez besoin, vous vérifiez la présence des fichiers voulus dans votre cache maison.</p>
<pre><code>if( localStorage.getItem('main.js') !== null ) {
    eval( localStorage.getItem('main.js') );
}</code></pre>
<p>Oui, vous faites à la main le boulot du navigateur (télécharger, gérer le cache, insérer…) mais c’est avec ce genre de code un peu extrême que l’expérience utilisateur sur mobile fera la différence. En prime, les navigateurs de bureau en profiteront aussi.</p>
<p>Une note pour ceux qui ont entendu dire que LocalStorage était contre-performant car synchrone (lorsque vous écrivez, vous bloquez le programme le temps que le disque ait fini de travailler) :</p>
<ul>
<li>c’est évitable facilement en passant par un wrapper qui va simplement effectuer l’écriture en asynchrone ;</li>
<li>les mobiles écrivant tout en RAM / Flash disk, les temps d’accès sont de toute façon négligeables.</li>
</ul>
<p>Vous pouvez encore passer au niveau supérieur en utilisant une technique qui a autant fait ses preuves que montré ses limites : l’utilisation de la <a href="http://appcachefacts.info/">spécification Application Cache</a>. <strong>Native, bien supportée par tous les navigateurs modernes mobiles ou de bureau</strong>, elle permet de déclarer en un fichier (le manifeste) quels sont les fichiers à télécharger, quelles ressources doivent continuer à être servies en ligne, et quoi afficher lorsque la connexion n’est plus là. Au contraire de la gestion du cache présentée précédemment qui est personnalisée et donc très adaptée à votre application, Application Cache vous force à coder d’une certaine manière (maîtriser absolument toutes ses URLs), présente certains manques (invalider le cache de certains fichiers seulement) et il faut un petit temps d’adaptation pendant la phase de développement pour comprendre son fonctionnement intrinsèque. En revanche, en terme de performance et de mode de distribution, c’est parfait !</p>
<h2>4. Réduire la taille</h2>
<h3>Minification et compression des JS / CSS</h3>
<p>La minification est généralement exécutée au déploiement du site juste après la concaténation et vous pouvez généralement gagner 50 % du poids des fichiers avec des outils solides comme <a href="http://yuilibrary.com/projects/yuicompressor/">YUI Compressor</a>. Activez la compression gzip par-dessus et vous aurez gagné au final 90 % du poids initial de vos fichiers. Sachant qu’il n’est plus rare de trouver des sites avec 200-500 Ko de CSS et de JS, le gain est assez important.</p>
<h3>Les photos</h3>
<p>Pour les images de l’interface, comme pour les photos, vous avez beaucoup à gagner en compressant au maximum les images servies. Encore plus efficace : ne les afficher que si elles sont nécessaires. Dans le cas d’une application Web Mobile ou l’interface permet de beaucoup scroller, considérez comme une amélioration majeure de faire du lazy-loading sur les images, c’est à dire de ne télécharger l’image que lorsqu’elle est sur le point d’être affichée.<br />
En terme de compresseur d&rsquo;image sans perte de qualité, voyez avec <a href="http://advsys.net/ken/utils.htm">PNGout</a> (ligne de commande) et <a href="http://pnggauntlet.com/">PNG Gauntlet</a>  (son interface visuelle) pour compresser efficacement les PNG, ou <a href="http://sauron.jyu.fi/cgi-bin/viewcvs.cgi/jpegoptim/">JPGoptim</a> (ligne de commande) et <a href="http://imageoptim.com/">Image Optim</a> (meta interface pour Mac) pour les JPG.</p>
<h3>Les cookies</h3>
<p>Là aussi, investissez du temps pour maîtriser toutes les URLs de toutes les ressources statiques de votre site , afin de les mettre sur des domaines séparés du domaine principal. Imaginez un cookie d’un peu moins d’un Ko qui serait envoyé à la centaine d’objets généralement appelée par une page Web classique : vous demandez à votre utilisateur d’uploader 100 Ko de données inutiles. Une autre piste pour remplacer les cookies qui sont parfois servis sur des pages statiques qui n’utilisent même pas de données personnalisées est de ne pas les utiliser du tout… pour les remplacer par HTML5 localStorage si vous avez tout de même besoin de persistance côté client (préférence d’affichage, historique…). Pour la compatibilité navigateur, passez par des petites librairies spécialisées.</p>
<p><H1>En résumé</h1>
<p>Vous voilà donc paré pour arrêter de perdre vos clients dès qu’ils essayent d’accéder à votre site à partir d’un réseau mobile. Nous avons vu que :</p>
<ul>
<li>la performance est empirique : testez même les grands classiques avant de choisir vos solutions ;</li>
<li>la plupart des techniques déjà connues marchent mais sont à traiter dans un autre ordre ;</li>
<li>ces techniques sont à pousser dans leurs extrêmes ;</li>
<li>de nouvelles possibilités sont apparues.</li>
</ul>
<p>Et ne comptez pas sur l’évolution future de l’équipement réseau : sauf inversion de la tendance actuelle, non seulement vos sites vont continuer à grossir mais en plus les futurs utilisateurs des réseaux 4G voire Wimax auront toujours des doigts, des murs, des gens et de l’atmosphère à traverser avant d’arriver sur vos serveurs.</p>
<p>L’optimisation, c’est maintenant.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/braincracking?a=RNxe7EgtV5k:sZCHVcC6irU:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/braincracking?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=RNxe7EgtV5k:sZCHVcC6irU:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/braincracking?i=RNxe7EgtV5k:sZCHVcC6irU:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=RNxe7EgtV5k:sZCHVcC6irU:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/braincracking?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=RNxe7EgtV5k:sZCHVcC6irU:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/braincracking?i=RNxe7EgtV5k:sZCHVcC6irU:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=RNxe7EgtV5k:sZCHVcC6irU:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/braincracking?i=RNxe7EgtV5k:sZCHVcC6irU:V_sGLiPBpWU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/braincracking/~4/RNxe7EgtV5k" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://braincracking.org/2012/11/06/performance-web-mobile-chargement-de-page-22/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://braincracking.org/2012/11/06/performance-web-mobile-chargement-de-page-22/</feedburner:origLink></item>
		<item>
		<title>Performance web mobile, chargement de page 1/2</title>
		<link>http://feedproxy.google.com/~r/braincracking/~3/Lg9NJ9g1UP0/</link>
		<comments>http://braincracking.org/2012/11/06/performance-web-mobile-chargement-de-page-12/#comments</comments>
		<pubDate>Tue, 06 Nov 2012 20:51:17 +0000</pubDate>
		<dc:creator>jpvincent</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Performances]]></category>
		<category><![CDATA[Perfs]]></category>

		<guid isPermaLink="false">http://braincracking.org/?p=1156</guid>
		<description><![CDATA[Cet article a été initialement publié sur le train de 13h37, magazine du développement web de grande qualité, qui a le double mérite de rémunérer ses auteurs et de proposer les articles avec une licence CC BY-NC-SA. Introduction Vos utilisateurs viennent chez vous sur mobile : 5 % selon StatsCounter ; 10 % selon ATInternet [...]]]></description>
			<content:encoded><![CDATA[<p><em>Cet article a été initialement publié sur <a title="le train de 13h37" href="http://letrainde13h37.fr/14/performance-web-mobile-chargement-de-page-1-sur-2/">le train de 13h37</a>, magazine du développement web de grande qualité, qui a le double mérite de <a href="http://letrainde13h37.fr/rejoignez-nous/">rémunérer</a> ses auteurs et de proposer les articles avec une licence <a href="http://creativecommons.org/licenses/by-nc-sa/2.0/fr/">CC BY-NC-SA</a>.</em></p>
<h1>Introduction</h1>
<p>Vos utilisateurs viennent chez vous sur mobile : <a href="http://gs.statcounter.com/#mobile_vs_desktop-FR-monthly-201208-201210">5 % selon StatsCounter</a> ; <a href="http://www.atinternet.fr/documents/systemes-dexploitation-pres-de-7-des-visites-europeennes-pour-ios/">10 % selon ATInternet</a> ; 9 % d’après ce que je vois chez mes clients dont le site n’a PAS été pensé pour du mobile. Évidemment cette part est en augmentation constante, a déjà largement dépassé IE7, va dépasser IE8, et il est raisonnable de penser que, ces statistiques étant récoltées via JavaScript, certaines tentatives d’accès ne soient même pas comptabilisées ! Que vous le vouliez ou non, que votre site ait été fait ou pas pour cet usage, <strong>vos utilisateurs essaient de venir sur votre site dans des conditions de réseau qui ne vous arrangent pas forcément</strong>, mais qui vont vous poser quelques défis intéressants.</p>
<h1>De quels mobiles parle-t-on ?</h1>
<p>Plus on rentre dans les détails des navigateurs, des systèmes d’exploitation et des capacités matérielles, et plus il semble illusoire de définir ce qu’est vraiment un mobile. Restons pragmatiques et, dans le cadre de cet article sur la performance, précisons ce que nous allons considérer comme notre cible :</p>
<ul>
<li>capacité du navigateur à afficher des sites non spécifiquement prévus pour mobiles ;</li>
<li>navigation &laquo;&nbsp;tactile&nbsp;&raquo; ;</li>
<li>matériel sous-dimensionné par rapport à la machine de bureau moyenne ;</li>
<li>qualité de réseau fluctuante.</li>
</ul>
<p>Ce dernier critère peut prêter à discussion, tant on observe d’utilisateurs mobiles accéder aux sites depuis le confort du WiFi de la maison : par exemple, la moitié des visiteurs dits &laquo;&nbsp;mobile&nbsp;&raquo; sont en fait sur iPad, ce qui implique (le plus souvent) le WiFi.</p>
<p>Mais dans le cadre de cet article nous allons surtout nous intéresser aux &laquo;&nbsp;problèmes supplémentaires à résoudre pour le chargement des pages&nbsp;&raquo; : les temps de chargement depuis une tablette / mobile sur WiFi sont largement comparables aux temps de chargement sur certains navigateurs de bureau.</p>
<h1>Comment tester ?</h1>
<p>Tout développement commence par la mise dans de bonnes conditions pour tester ; la mesure a lieu ensuite dans un chantier performance web. Le banc de test idéal pour le mobile est simplement impossible à monter et force est de constater que les éditeurs de sites, de l’indépendant aux sites avec des millions de pages vues, se contentent généralement de l’iPhone de l’intégrateur et éventuellement de l’Android-qui-s’appelle-revient du collègue.</p>
<p>Si l’on regarde les parts de marché en France, cela correspond effectivement à une réalité : nous avons Safari pour iOS partagé entre les différents iPhone et iPad, et le navigateur par défaut d’Android distribué avec les version 2.x. En queue de peloton et souvent ignorés, à tort pour les valeurs d’interopérabilité du Web, viennent les Opera (mini ou mobile) pourtant ultradominants dans d’autres pays, Firefox mobile, ainsi que différentes variantes de Webkit sur les OS mobiles survivants (Blackberry, SymbianOS, LG…), ainsi que IE Windows.</p>
<p>Ah, et ne comptez pas sur les émulateurs : ils sont déjà à peine acceptables pour tester les fonctionnalités, alors question performance ils sont tout simplement disqualifiés d’office ! Entre l’utilisation du processeur de la machine hôte, une connexion filaire sans défaut et les approximations inhérentes à tout émulateur, vous n’aurez jamais quoi que ce soit de réaliste dans votre quête de la fluidité.</p>
<p>La solution minimale du pauvre, c’est de conserver ses mobiles et d’attendre qu’ils vieillissent ou d’acheter des occasions datant d’un an ou deux, sans mettre à jour le système d’exploitation. Pour simuler un réseau 3G, on pourra utiliser des proxys via WiFi qui dégradent volontairement la connexion. Il y a une grosse dizaine de solutions, généralement limitées à un seul OS (souvent Mac). La plus compatible et reconnue est le proxy payant <a href="http://www.charlesproxy.com/">Charles</a> mais la gratuité de <a href="http://www.jopa.fr/index.php/2010/07/17/limiter-la-bande-passante-avec-trickle/">Trickle</a> (Linux), <a href="http://osxdaily.com/2011/08/10/simulate-internet-connectivity-bandwidth-speeds-network-link-conditioner/">Network Link Conditioner</a> (OSX 10.6) ou <a href="http://slowyapp.com/">Slowy App</a> (OSX 10.5) peut vous séduire.</p>
<p>Le principe est simple : ces logiciels contiennent de quoi dégrader artificiellement une connexion (débit, latence, perte de paquets). Vous configurez votre téléphone pour utiliser votre machine comme proxy via WiFi, et voilà ! En prime, vous pouvez analyser les trames réseau qui passent. C’est moins cher que de vraies cartes SIM et la constance de la dégradation permet de faire des tests répétés, là où la qualité d’un vrai réseau data peut varier d’une minute à l’autre.</p>
<p>Pour être honnête, les techniques décrites dans cet article ont surtout été testées sur le navigateur Android 2.3 et Safari iOS 6, avec des vérifications fonctionnelles sur Firefox et Opera mobile sur Android, les deux absents notoires étant le Safari de Blackberry et Internet Explorer.</p>
<p>Signalons également que nous ignorons délibérément un bon milliard d&rsquo;habitants sur cette planète qui se connectent au Net avec des mobiles pré-smartphones : techniquement difficiles à adresser sérieusement, ils sont également une minorité en France à posséder ces anciens mobiles et avoir souscrit un abonnement 3G.</p>
<h1>Chargez !</h1>
<h2>L’importance du réseau</h2>
<p>Croyez-le ou non, <strong>les débits théoriques en 3G et technologies au-delà peuvent être plus rapides que les débits constatés des ADSL</strong>. Mais comme finalement assez peu de gens font du Web depuis les laboratoires de tests des constructeurs, il va falloir composer avec la réalité physique : une couverture nuageuse un peu forte, un déplacement un peu rapide, <a href="http://www.clubic.com/smartphone/iphone/actualite-349254-iphone-4-reponse-steve-jobs-probleme-reception.html">un doigt mal placé</a>, un mur un peu épais, ou des gens autour de vous également équipés de mobiles (incroyable en 2012), et vous vous retrouvez rapidement avec des débits ridicules, des pertes de paquets énormes et le sentiment global qu’on vous a un peu survendu la &laquo;&nbsp;meilleure couverture réseau de France&nbsp;&raquo;.</p>
<p>Lorsque le réseau marche, l’utilisateur français moyen a <strong>en moyenne 2,50 Mb/s</strong> (<a href="http://letrainde13h37.fr/23/debit-latence-france-bien-calibrer-tests-performance/">sources</a>) ce qui est plus rapide que 25% des ADSL de France. Par contre, la latence ou ping est en moyenne à 200 ms soit le double de la moyenne en ADSL.</p>
<p>Depuis <a href="http://www.belshe.com/2010/05/24/more-bandwidth-doesnt-matter-much/">toujours</a>, la latence est l’ennemi numéro 1 de nos pages Web. Ceci est du à <a href="http://www.slideshare.net/edaspet/soire-webperf-du-29-nov-2010-latence-et-cdn">la nature même de HTTP</a> et signifie que pour un débit moyen seulement deux fois inférieur, le temps de chargement sera en fait 3 à 6 fois plus long sur mobile ! Pire, la perte de paquets est assez conséquente et inhérente à la technologie radio utilisée pour communiquer entre le mobile et l’antenne de l’opérateur. Et cette perte de paquets arrive plus fréquemment pour les petites requêtes… Exactement la manière dont sont composées la majorité de nos pages Web actuelles !</p>
<p>Ajoutez à cela qu’accrocher et maintenir le réseau data est une des opérations les plus coûteuses en terme de batterie : passez en mode avion sur votre smartphone, utilisez-le presque comme d’habitude (lectures, jeux…) et vous verrez qu’il peut tenir une seconde journée sans recharge. Et souvenez-vous des anciens portables sans data qui tenaient une semaine…</p>
<p>Bref, c’en est au point que les constructeurs optimisent comme ils peuvent le matériel, par exemple en mettant en veille la radio après un certain temps d’inutilisation. On se retrouve donc dans des situations où, le temps de lire cet article, l’antenne s’est déconnectée et il vous faudra plusieurs secondes pour que la requête suivante aboutisse !</p>
<p>Malgré cela, les utilisateurs ne sont pas beaucoup plus patients que sur un ordinateur de bureau : après 5 à 10 secondes de page blanche, une majorité d’utilisateurs a déjà rebroussé chemin, et autant vous dire qu’ils n’apparaissent même pas sur les statistiques collectées en JavaScript. Comment faire pour vaincre l’hémorragie de visiteurs et proposer des services de meilleure qualité perçue ?</p>
<p>Eh bien il va nous falloir revisiter tout l’arsenal des classiques de la Performance Web.</p>
<h2>Remettre en cause les classiques</h2>
<p>Lorsque le pape de la performance, Steve Souders, a émis chez Yahoo! <a href="http://developer.yahoo.com/performance/rules.html">les premières recommandations de performance Web</a>, c’était en faisant du reverse-engineering sur les moteurs IE6-IE7 et Firefox 2. C’était en 2005 et, avec l’abandon progressif du support de ces navigateurs antédiluviens (à l’échelle du Web) d’un côté et la banalisation de l’ADSL de l’autre, certaines règles ou astuces sont devenues moins importantes.</p>
<p>L’apparition de la navigation sur mobile en a même rendu certaines dangereuses !</p>
<h3>Le domain-sharding</h3>
<p>Citons par exemple le domain-sharding, qui consiste à répartir ses fichiers statiques sur plusieurs sous-domaines différents. Étonnamment populaire, à l’origine cette technique permettait de passer outre la limitation à 2 files de téléchargement par domaine et de bénéficier de toute la largeur des bandes passantes modernes. Mais à partir de IE8, sorti en 2009, cette technique devient inutile car le nombre de téléchargements simultanés passe de 2 à généralement 6 : les navigateurs se sont adaptés à la banalisation des gros débits et tentent d’en tirer parti.</p>
<p>Utilisons le service <a href="http://stevesouders.com/cuzillion/">Cuzillon</a> qui va nous permettre de <a href="http://stevesouders.com/cuzillion/?c0=bi1hfff0_0_f&amp;c1=bi1hfff0_0_f&amp;c2=bi1hfff0_0_f&amp;c3=bi1hfff0_0_f&amp;c4=bi1hfff0_0_f&amp;c5=bi1hfff0_0_f&amp;c6=bi2hfff0_0_f&amp;c7=bi2hfff0_0_f&amp;c8=bi2hfff0_0_f&amp;c9=bi2hfff0_0_f&amp;c10=bi2hfff0_0_f&amp;c11=bi2hfff0_0_f&amp;c12=bi3hfff0_0_f&amp;c13=bi3hfff0_0_f&amp;c14=bi3hfff0_0_f&amp;c15=bi3hfff0_0_f&amp;c16=bi3hfff0_0_f&amp;c17=bi3hfff0_0_f&amp;c18=bi4hfff0_0_f&amp;c19=bi4hfff0_0_f&amp;c20=bi4hfff0_0_f&amp;c21=bi4hfff0_0_f&amp;c22=bi4hfff0_0_f&amp;c23=bi4hfff0_0_f&amp;t=1344287686190">simuler une page avec 24 images réparties sur 4 domaines</a> et <a href="http://stevesouders.com/cuzillion/?c0=bi1hfff0_0_f&amp;c1=bi1hfff0_0_f&amp;c2=bi1hfff0_0_f&amp;c3=bi1hfff0_0_f&amp;c4=bi1hfff0_0_f&amp;c5=bi1hfff0_0_f&amp;c6=bi1hfff0_0_f&amp;c7=bi1hfff0_0_f&amp;c8=bi1hfff0_0_f&amp;c9=bi1hfff0_0_f&amp;c10=bi1hfff0_0_f&amp;c11=bi1hfff0_0_f&amp;c12=bi1hfff0_0_f&amp;c13=bi1hfff0_0_f&amp;c14=bi1hfff0_0_f&amp;c15=bi1hfff0_0_f&amp;c16=bi1hfff0_0_f&amp;c17=bi1hfff0_0_f&amp;c18=bi1hfff0_0_f&amp;c19=bi1hfff0_0_f&amp;c20=bi1hfff0_0_f&amp;c21=bi1hfff0_0_f&amp;c22=bi1hfff0_0_f&amp;c23=bi1hfff0_0_f&amp;t=1344289103427">une autre page avec 24 images sans domain-sharding</a>. Le service <a href="http://www.webpagetest.org/">WebPageTest</a> nous permet de voir qu’il y avait effectivement une amélioration sur le temps de chargement sur IE7 :</p>
<div id="attachment_1158" class="wp-caption alignnone" style="width: 1261px"><a href="http://braincracking.org/wp-content/uploads/2012/11/ie7-sharding.png"><img class="size-full wp-image-1158" title="ie7-sharding" src="http://braincracking.org/wp-content/uploads/2012/11/ie7-sharding.png" alt="" width="1251" height="286" /></a><p class="wp-caption-text">WebPagetest – Test de chargement d’une page sous IE7 avec (en bas) et sans sharding (en haut). <a href="http://www.webpagetest.org/video/compare.php?tests=120806_f7a9cc3a9bae3fff71e1ac524842bca3%2C120806_379be6337c90ce0cb2273ad4d88a709e&amp;thumbSize=200&amp;ival=500&amp;end=all">Voir la source</a></p></div>
<p>Le test sur les mêmes URLs sur IE8 nous montre que l’on ne gagne plus grand chose en premier rendu (les petites images chargées) :</p>
<div id="attachment_1159" class="wp-caption alignnone" style="width: 1068px"><a href="http://braincracking.org/wp-content/uploads/2012/11/ie8-sharding.png"><img class="size-full wp-image-1159" title="ie8-sharding" src="http://braincracking.org/wp-content/uploads/2012/11/ie8-sharding.png" alt="" width="1058" height="278" /></a><p class="wp-caption-text">WebPagetest – Test de chargement d’une page sous IE8 avec (en bas) et sans sharding (en haut). <a href="http://www.webpagetest.org/video/compare.php?tests=120806_c2e00161edfe350d8d77969b44361ccc,120806_a0162c681568ff998a5cb40f6c03b8cd">Voir la source</a></p></div>
<p>On ne gagne plus rien car la parallélisation des téléchargements est assurée de base par le navigateur. On a en fait rajouté deux mini-problèmes en rajoutant un temps de résolution DNS supplémentaire par domaine, et en faisant concourrir plusieurs images pour la même bande passante. Je dis &laquo;&nbsp;mini-problème&nbsp;&raquo; en supposant qu’on ne ciblait que les navigateurs de bureau (c’est mal) où ces problèmes sur des vrais sites (75-150 requêtes, 10-15 domaines) passent finalement inaperçus, mais vous ciblez les mobiles, pas vrai ?</p>
<p>Sur mobile, les navigateurs ouvrent également plusieurs connexions par domaine et font même du multiplexing HTTP (plusieurs requêtes HTTP dans le même tuyau TCP) pour minimiser les problèmes liés à la latence. Vous prenez alors le risque de couper court à ces optimisations. Résultat ?</p>
<div id="attachment_1160" class="wp-caption alignnone" style="width: 817px"><a href="http://braincracking.org/wp-content/uploads/2012/11/ios-sharding.png"><img class="size-full wp-image-1160" title="ios-sharding" src="http://braincracking.org/wp-content/uploads/2012/11/ios-sharding.png" alt="" width="807" height="495" /></a><p class="wp-caption-text">WebPagetest – Test de chargement d’une page sous iOS avec (en bas) et sans sharding (en haut). <a href="http://www.webpagetest.org/video/compare.php?tests=120806_K6_W44,120806_EZ_W36">Voir la source</a></p></div>
<p><strong>L’affichage a été ralenti</strong> ! En forçant encore plus de domaines, vous demandez à plus d’objets de se partager la même bande passante, que vous devez considérer a priori comme rare sur mobile. Donc vous ralentissez l’affichage des premières images alors même que les suivantes ne sont pas immédiatement utiles. Ici, le temps de chargement total est en plus augmenté car le multiplexing n’a pas pu être utilisé, ce qui peut être le cas sur des sites avec un ratio ressources / domaine faible.</p>
<h3>Les scripts en bas de page</h3>
<p>Le temps avant le premier rendu (l’affichage des premiers pixels du site) est un peu le but ultime de la performance Web, car il y a une très forte corrélation entre ce temps et une augmentation des taux de transformation ( + rapide = + d’argent ).</p>
<p>Dans ce cadre, une autre technique populaire consiste à déplacer toutes les balises script en bas de page. Cette technique marche effectivement bien sur les anciens navigateurs et continue à faire ses preuves dans une moindre mesure sur les nouveaux malgré leurs progrès dans la prioritisation des téléchargements.</p>
<p>Regardons <a href="http://www.webpagetest.org/video/compare.php?tests=120806_K3_WTX,120806_PB_WT9">l’effet attendu avec IE8</a> sur une page simple où le téléchargement du JavaScript est retardé côté serveur.</p>
<div id="attachment_1161" class="wp-caption alignnone" style="width: 2086px"><a href="http://braincracking.org/wp-content/uploads/2012/11/desktop-scriptsbottom.png"><img class="size-full wp-image-1161" title="desktop-scriptsbottom" src="http://braincracking.org/wp-content/uploads/2012/11/desktop-scriptsbottom.png" alt="" width="2076" height="298" /></a><p class="wp-caption-text">Bureau : tests de comparaison de chargement d’une page avec les scripts en bas et en haut de page. <a href="http://www.webpagetest.org/video/compare.php?tests=120806_K3_WTX,120806_PB_WT9">voir la source</a></p></div>
<p>En haut, la page améliorée par déplacement des balises script ; on voit que le contenu (une simple phrase) s’affiche rapidement, alors qu’en bas la page blanche de la mort est de rigueur.</p>
<p>Passons sur mobile, si vous le voulez bien, et <a href="http://www.webpagetest.org/video/compare.php?tests=120806_A9_WQE,120806_BA_WQ9">testons Safari iOS et Android Browser 2.3.</a></p>
<div id="attachment_1162" class="wp-caption alignnone" style="width: 1804px"><a href="http://braincracking.org/wp-content/uploads/2012/11/mobiles-scriptsbottom.png"><img class="size-full wp-image-1162" title="mobiles-scriptsbottom" src="http://braincracking.org/wp-content/uploads/2012/11/mobiles-scriptsbottom.png" alt="" width="1794" height="509" /></a><p class="wp-caption-text">Mobiles Android et iOS : tests de comparaison de chargement d’une page avec les scripts en bas de page. <a href="http://www.webpagetest.org/video/compare.php?tests=120806_A9_WQE,120806_BA_WQ9">Voir la source</a></p></div>
<p>Android se comporte comme nos navigateurs de bureau et affiche le contenu dès qu’il l’a. Safari iOS préfère attendre le script avant d’afficher quoi que ce soit, sans doute par peur du FOUC (<em>Flash Of Unscripted Content</em>).</p>
<p>On peut débattre sur le fait qu’ergonomiquement il vaut mieux attendre une page bien faite (complètement scriptée) plutôt que d’afficher rapidement du contenu pas finalisé, mais <strong>les taux de tranformation montrent que l’affichage rapide rapporte plus</strong>.<br />
Et de toute façon, en tant qu’auteur de la page, c’est à vous de juger si elle peut être vue momentanément sans scripting ou pas : si vous utilisez des méthodes de développement par couche (HTML, puis CSS, puis JS), ça devrait être bon. Si vous voulez de la performance, il va donc falloir faire évoluer votre technique d’inclusion de script pour passer à une version asynchrone.</p>
<p>Le chargement asynchrone à la base est bête comme chou :</p>
<pre><code>var oNode = document.createElement('script'); 
oNode.type = 'text/javascript'; 
oNode.src = 'http://domaine/monscript.js'; 
document.getElementsByTagName('head')[0].appendChild(oNode); </code></pre>
<p>Vous utilisez le DOM pour créer dynamiquement de nouveaux noeuds script qui vont charger des fichiers JS. Cette technique est notamment utilisée par les Google Analytics, boutons G+ et autres Like Facebook pour s’insérer dans vos sites sans introduire de dépendance forte vis-à-vis de leurs serveurs.<br />
Autrement dit, lorsque leurs serveurs sont en rade ou bloqués par un proxy, le navigateur va tout de même afficher votre page (trop aimable). Utiliser cela avec ses propres scripts est globalement une bonne idée, et <strong>devient vital sur mobile</strong>. Vous aurez probablement besoin d’aller plus loin avec le chargement dynamique de scripts (exécuter du code lorsque le fichier est arrivé, gestion des dépendances et de l’ordre de chargement, concaténation de fichiers à la volée…), aussi pensez à utiliser des frameworks solides comme <a href="http://requirejs.org/">requireJS</a>, <a href="http://yepnopejs.com/">YepNope.js</a> (inclus avec Modernizr), <a href="http://headjs.com/">HeadJS</a>, <a href="http://labjs.com/">LabJS</a>… Chacun a sa philosophie.<br />
Et puisque je vous tiens, voici le mien : <a href="https://github.com/jpvincent/LazyLoadLight">LazyLoadLight</a>, qui se veut léger et facile <img src='http://braincracking.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Voir <a href="http://braincracking.org/?p=1164">la suite de cet article</a> qui parle des chemins à explorer pour des pages toujours plus rapides sur mobile.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/braincracking?a=Lg9NJ9g1UP0:lAnQyIvBLTs:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/braincracking?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=Lg9NJ9g1UP0:lAnQyIvBLTs:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/braincracking?i=Lg9NJ9g1UP0:lAnQyIvBLTs:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=Lg9NJ9g1UP0:lAnQyIvBLTs:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/braincracking?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=Lg9NJ9g1UP0:lAnQyIvBLTs:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/braincracking?i=Lg9NJ9g1UP0:lAnQyIvBLTs:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=Lg9NJ9g1UP0:lAnQyIvBLTs:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/braincracking?i=Lg9NJ9g1UP0:lAnQyIvBLTs:V_sGLiPBpWU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/braincracking/~4/Lg9NJ9g1UP0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://braincracking.org/2012/11/06/performance-web-mobile-chargement-de-page-12/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://braincracking.org/2012/11/06/performance-web-mobile-chargement-de-page-12/</feedburner:origLink></item>
		<item>
		<title>HTML5, aujourd’hui</title>
		<link>http://feedproxy.google.com/~r/braincracking/~3/ao2sNdxi0BI/</link>
		<comments>http://braincracking.org/2012/02/01/html5-aujourdhui/#comments</comments>
		<pubDate>Wed, 01 Feb 2012 07:30:15 +0000</pubDate>
		<dc:creator>jpvincent</dc:creator>
				<category><![CDATA[HTML5]]></category>
		<category><![CDATA[historique]]></category>
		<category><![CDATA[introduction]]></category>

		<guid isPermaLink="false">http://braincracking.org/?p=923</guid>
		<description><![CDATA[L&#8217;article suivant est la retranscription de l&#8217;article que j&#8217;ai écrit pour le magazine PHP Solutions, dans le numéro hors série de 2011 consacré à HTML5. Le monde compliqué du droit d&#8217;auteur veut que ce texte ne m&#8217;appartienne pas, c&#8217;est donc avec leur permission express que j&#8217;en fait bénéficier mes lecteurs (oui toi). Toute reproduction est [...]]]></description>
			<content:encoded><![CDATA[<p>L&rsquo;article suivant est la retranscription de l&rsquo;article que j&rsquo;ai écrit pour <a href="http://phpsolmag.org/">le magazine PHP Solutions</a>, dans le numéro hors série de 2011 consacré à HTML5. Le monde compliqué du droit d&rsquo;auteur veut que ce texte ne m&rsquo;appartienne pas, c&rsquo;est donc avec leur permission express que j&rsquo;en fait bénéficier mes lecteurs (oui toi). Toute reproduction est donc interdite.</p>
<p>Cet article se veut une introduction générale à HTML5, notamment pour les développeurs PHP qui sont généralement les mieux placés pour prendre au sérieux ce qu&rsquo;il se passe au frontend. Si vous avez lu <a href="http://livre-html5.com/">mon livre sur HTML5</a> ou que vous suivez déjà régulièrement l&rsquo;actualité, je doute que vous y appreniez grand chose. Il explique :</p>
<ul>
<li>l&rsquo;origine de la spécification</li>
<li>comment les sites d&rsquo;aujourd&rsquo;hui peuvent en bénéficier</li>
<li>le futur des applications Web</li>
<li>les rares synergies entre HTML5 et PHP</li>
</ul>
<h2>Historique</h2>
<h3>Une définition variable</h3>
<p>Le terme même « HTML5 » couvre plusieurs définitions, et nous allons voir que le W3C a surpris tout le monde dans son choix final. Avant que le terme HTML5 n&rsquo;apparaisse, HTML 4.01 était stabilisé et le W3C planchait sur XHTML 2 car pour eux la syntaxe stricte de XML allait permettre à tous les navigateurs d&rsquo;être enfin d&rsquo;accord sur les règles de <em>parsing</em>des pages.<br />
<span id="more-923"></span><br />
<div id="attachment_924" class="wp-caption aligncenter" style="width: 111px"><img class="size-full wp-image-924" title="logo_whatwg" src="http://94.23.51.58/jpvincent/blog/wp-content/uploads/2012/01/html5_intro_figure_01.png" alt="" width="101" height="101" /><p class="wp-caption-text">Le logo volontairement énigmatique du WHATWG</p></div></p>
<p>Nous sommes en 2004 et des représentants d&rsquo;Apple, Opéra et Mozilla, pensant que XHTML 2 est une fausse bonne idée, décident de former un groupe dissident, dénommé non sans ironie WHATWG (What Working Group?). Ils travaillent de leur côté à leur vision du Web : celle d&rsquo;une plateforme de développement universelle qui pourrait battre les applications natives, aux langages généralement propriétaires et fermés, en étant exécutable sur tous les systèmes et toutes les machines. Leur première spécification est « WebForms 2 », une évolution majeur des formulaires HTML que nous allons aborder plus loin. Vont venir s&rsquo;ajouter beaucoup de petites spécifications regroupées sous le terme « Web Application 1 ».</p>
<p>En 2006 le terme HTML5 apparaît enfin : c&rsquo;est la version approuvée par le W3C des spécifications travaillées par le WHATWG. Le Web a eu peur un instant que le W3C soit tellement discrédité par cette affaire que ses spécifications, déjà mal comprises des développeurs Web par la faute des implémentations non conformes de certains navigateurs, ne fassent plus autorité. Désormais cette réconciliation donne un nouveau rythme de travail : les navigateurs (hors Microsoft) testent des implémentations de fonctionnalité à toute vitesse, s&rsquo;accordent sur les APIs finales et les formalisent, pendant que le W3C garde son rôle de gardien des clés et continue son travail de proposition de spécifications.</p>
<p>En 2009, le W3C accuse le coup du rejet par la communauté des développeurs Web de XHTML 2 et l&rsquo;abandonne : l&rsquo;inconvénient majeur de la syntaxe XML était qu&rsquo;elle ne serait jamais rétrocompatible avec les navigateurs déjà en circulation. A cette époque déjà on a du mal à savoir ce que désigne vraiment HTML5 : des spécifications d&rsquo;API sont réparties entre trois spécifications (« Web Application », « HTML5 » par le WHATWG et « HTML5 » par le W3C), et certaines devenues trop grosses ou pratiquement finalisées sont carrément sorties de HTML5 pour vivre par elle même.</p>
<div id="attachment_925" class="wp-caption aligncenter" style="width: 266px"><img class="size-full wp-image-925" title="logo_html5" src="http://94.23.51.58/jpvincent/blog/wp-content/uploads/2012/01/html5_intro_figure_02.png" alt="" width="256" height="256" /><p class="wp-caption-text">Le logo officiel de HTML5</p></div>
<p>En 2011 le terme HTML5 est clairement un terme générique : le W3C déclare officiellement qu&rsquo;il désigne désormais plus une idée de l&rsquo;évolution du Web qu&rsquo;une spécification en particulier, et lui donne par la même occasion un <strong>logo</strong>. Le WHATWG de soncôté bannit ce terme pour renommer ses spécifications « living standard », ce que l&rsquo;on pourrait traduire par : « ne cherchez pas la stabilité chez nous, allez plutôt voir le W3C pour ça ».</p>
<p>&nbsp;</p>
<p>Le HTML5 dont nous allons parler ici désigne trois choses :</p>
<ul>
<li>l&rsquo;évolution de HTML 4, avec une syntaxe assouplie, une nouvelle sémantique et l&rsquo;introduction des <strong>microdata</strong>,</li>
<li>de nouvelles interactions 		utilisateur, avec les nouveaux formulaires, la géolocalisation et 		le multimédia</li>
<li>l&rsquo;arrivée des applications Web 		avec des API JavaScript comme <strong>Websocket</strong> pour la 		communication temps réel, la gestion du hors ligne, le stockage 		d&rsquo;informations côté client et <strong>XMLHTTPRequest 2</strong></li>
</ul>
<p>Nous avons choisi ces sujets car ce sont que vous pourrez utiliser en production le plus immédiatement, en assurant une compatibilité avec tous les navigateurs depuis Internet Explorer 6.</p>
<h3>Quand HTML5 sera-t-il prêt ?</h3>
<p>Réponse courte : maintenant, et depuis plusieurs années déjà. Lisez la réponse longue pour comprendre de quoi HTML5 est fait.</p>
<h4>2022 ?</h4>
<p>A l&rsquo;époque où le WHATWG commença à travailler sur la spécification en 2004, Ian Hickson, l&rsquo;éditeur de la spécification, avait annoncé une date qui est restée longtemps dans la mémoire des journalistes : 2022. Il faut bien comprendre qu&rsquo;il faisait référence aux critères du W3C : des spécifications complètes, finalisées, acceptées, et surtout avec au moins deux implémentations complètement interopérables. Cela semble raisonnable à première vue, mais concrètement ce niveau de qualité repousse très loin les dates de finalisation. Par exemple après 10 ans d&rsquo;existence et d&rsquo;utilisation en production, CSS 2.1 vient à peine d&rsquo;atteindre le niveau final des spécifications : <em>« Recomendation »</em>. Et malgré cela il n&rsquo;existe pas encore deux navigateurs implémentant <strong>toutes</strong> les fonctionnalités, et sûrement pas de manière identique. HTML 4.01 lui par contre a bien atteint le niveau <em>« Recomendation »</em> il y a 10 ans, et même si il n&rsquo;y a pas de test unitaire pour le prouver on peut considérer que plusieurs navigateurs interprètent le même code de la même manière. Mais cela ne change pourtant rien au quotidien des développeurs Web qui doivent assurer le support sur les navigateurs qui ont ignoré ou mal interprété les spécifications.</p>
<h4>2011 ?</h4>
<p>La mauvaise nouvelle, c&rsquo;est que l&rsquo;on vient de voir avec CSS2.1 et HTML 4.01 que l&rsquo;état d&rsquo;une spécification du W3C ne signifiait pas grand chose pour le développeur web. La bonne nouvelle, c&rsquo;est que pour HTML5 non plus l&rsquo;état de la spécification n&rsquo;a pas beaucoup d&rsquo;importance ! Ce qui compte vraiment c&rsquo;est :</p>
<ul>
<li>la stabilité des implémentations 	navigateur,</li>
<li>la possibilité d&rsquo;émuler la 	fonctionnalité sur les anciens navigateurs,</li>
<li>à défaut, l&rsquo;acceptation d&rsquo;une 	page non améliorée pour les anciens navigateurs</li>
</ul>
<p>Autre grande nouvelle : HTML5 n&rsquo;est pas fait d&rsquo;un bloc. La spécification se découpe en de nombreuses fonctionnalités séparées, n&rsquo;ayant parfois pas de lien entre elles, et chaque navigateur avance sur ses sujets favoris. Concrètement il y a aujourd&rsquo;hui une bonne dizaine de nouvelles fonctionnalités qui sont à la fois suffisamment stables, suffisamment répandues et en même temps simulables sur les anciens navigateurs, ce sont celles que nous allons couvrir rapidement aujourd&rsquo;hui et qui nous font dire que HTML5 est déjà là.</p>
<h4>1999 ?</h4>
<p>Poussons le raisonnement jusqu&rsquo;au bout : en découpant HTML5 en spécifications séparées, on arrive à des conclusions étranges ; Internet Explorer 5.5, sorti en 1999 est compatible avec certaines fonctionnalités HTML5 comme le <em>drag and drop</em>. Évidemment cela s&rsquo;est fait dans l&rsquo;autre sens, c&rsquo;est à dire qu&rsquo;un des premiers travaux du WHATWG a été de coucher sur le papier des fonctionnalités comme le <em>drag and drop</em> qui n&rsquo;avaient jamais été écrites. Cet exemple est là pour illustrer que la question du « quand » n&rsquo;a pas vraiment de sens.</p>
<p><strong>Conclusion</strong> : des fonctionnalités majeures associées à HTML5 sont disponibles dès maintenant pour des environnements de production, y compris avec la contrainte du support d&rsquo;anciens navigateurs.</p>
<h3>La philosophie</h3>
<p>HTML5 est né dans le conflit et avec la volonté d&rsquo;être pragmatique pour une adoption rapide. Cela lui confère un certain nombre de principes :</p>
<ul>
<li><strong>Un assouplissement des règles</strong>. 		En réaction aux travaux sur XHTML 2 qui impliquait la 		syntaxe stricte de XML dans les pages HTML, HTML5 est clairement 		permissif et enlève les attributs inutiles, les <code>doctype</code>s 		compliqués, enlève l&rsquo;obligation d&rsquo;utiliser des <em title="&quot;">quotes </em> et autorise les variations de casse.</li>
<li><strong>L&rsquo;unification des règles de 		<em>parsing</em></strong>. Les navigateurs respectant HTML5 implémentent le 		même algorithme d&rsquo;interprétation du texte HTML pour construire le 		DOM, c&rsquo;est à dire la représentation finale du document accessible 		en CSS et en JavaScript.</li>
<li><strong>La rétro-compatibilité</strong>. Au 		contraire de ce sur quoi s&rsquo;engageait le W3C à l&rsquo;époque, les 		nouvelles fonctionnalités sont introduites avec des syntaxes 		permettant au parc de navigateurs actuels (en partant de Internet 		Explorer 6) de ne pas « casser » les pages.</li>
<li><strong>Formalisation de l&rsquo;existant</strong>. Le 		WHATWG a commencé par écrire les spécifications de 		fonctionnalités jamais documentées auparavant et pourtant 		implémentées au prix de longues heures de <em>reverse 		engineering </em> par tous les navigateurs. Cela va de 		fonctionnalités complètes comme le <em>drag 		and drop </em>à des attributs DOM comme <code>.innerHTML</code>.</li>
</ul>
<p>On le voit, HTML5 a été pensé avec beaucoup de pragmatisme pour une adoption immédiate. Cela est du à la volonté des fabricants de navigateurs de faire avancer le Web. Une fois ces bases saines établies, ils ont maintenant les coudées franches pour rattraper les applications natives en terme de fonctionnalités.</p>
<h2>Après HTML4</h2>
<p>Avant l&rsquo;animation 2D, la vidéo ou des piles de JavaScript pour faire du logiciel, HTML5, c&rsquo;est d&rsquo;abord du code HTML ! La sémantique est revue, la syntaxe évolue et l&rsquo;accessibilité est prise en compte.</p>
<h3>Nouvelle syntaxe</h3>
<p>La modification la plus visible est bien sur l&rsquo;introduction du nouveau <code>doctype</code> :</p>
<pre><code>&lt;!doctype html&gt;</code></pre>
<p>Cela simplifie les choses et on est même en droit de se demander à quoi servaient les <code>doctype</code>s 4.01 <em>strict </em>ou <em>transitional</em>. Pour la petite histoire, Internet Explorer 6 n&rsquo;utilisait cette instruction que pour savoir dans quel mode de rendu CSS il fallait se mettre (<em>quirksmode</em> ou mode standard).</p>
<p>Autre simplification : la déclaration de l&rsquo;encodage de la page.</p>
<pre><code>&lt;meta charset="utf-8"&gt;</code></pre>
<p>Certains attributs comme <code>type</code> dont l&rsquo;absence est universellement bien interprétée peuvent maintenant disparaître :</p>
<pre><code>&lt;script&gt; alert('Iceberg droit devant'); &lt;/script&gt;
&lt;style&gt; #titanic { float: none; } &lt;/style&gt;
</code></pre>
<h3>nouvelle sémantique</h3>
<p>Plusieurs balises disparaissent carrément car elles ont été accusées de mélanger le fond et la forme. Citons celles qui étaient le plus couramment utilisé : <code>font</code>, <code>center</code>, <code>strike</code>, <code>u</code>, <code>big</code>, <code>frame</code>, <code>frameset</code> ou encore <code>acronym</code> et <code>applet </code>ainsi qu&rsquo;une petite dizaine d&rsquo;autres.</p>
<p>Les attributs suivants sont également frappés d&rsquo;obsolescence :</p>
<p><code>longdesc</code> et <code>name</code> sur la balise <code>img</code>, <code>scope</code> sur la balise <code>td</code>, <code>classid</code> sur la balise <code>object</code>, <code>target</code> sur la balise <code>link</code> ainsi qu&rsquo;une dizaine d&rsquo;autres.</p>
<p>Ont été remplacés pour laisser la place à CSS :</p>
<p><code>align</code>, <code>bgcolor</code>, <code>background</code>, <code>border</code>, <code>cellpadding</code> et <code>cellspacing</code> sur <code>table</code>, <code>height</code> sur <code>td</code> et <code>th</code>, <code>marginheight</code> et <code>scrolling</code> sur <code>iframe</code> ainsi qu&rsquo;une vingtaine d&rsquo;autres.</p>
<p>D&rsquo;autres changent subtilement de valeur sémantique. Il n&rsquo;y aurait pas assez de place dans ces colonnes pour ré-expliquer le sens de chacune d&rsquo;entre elles, aussi prenons la plus célèbre : <code>strong</code>. Avant, elle était censé désigner un mot qui devait se dire avec emphase (sur lequel on mettrait l&rsquo;accent à l&rsquo;oral). Cette fonction étant maintenant dévolue à la balise <code>em</code>, <code>strong</code> veut maintenant dire « mot important », ce qui colle avec l&rsquo;usage effectif qui en était fait aujourd&rsquo;hui, notamment en référencement.</p>
<p>Enfin et surtout, de nouvelles balises apparaissent, les plus importantes étant les balises dite <strong>de section </strong>: <code>section</code>, <code>article</code>, <code>aside</code>, <code>header</code>, <code>footer</code>. Elle sont utiles pour préciser un peu les zones de votre site que vous entouriez auparavant d&rsquo;une <code>div</code>, faute de mieux. Vous pouvez utiliser le chemin de décision suivant pour déterminer la nature de votre balise :</p>
<ul>
<li>le contenu est il indépendant du 	site et peut il être exporté sans ce contexte ? Par exemple un 	article de blog ou une fiche produit. Dans ce cas là, la balise 	<code>article</code> est toute 	indiquée</li>
<li>le contenu mérite au moins un 	titre et regroupe des informations sur la même thématique ? La 	balise section est faite pour ça et vous permet de marquer par exemple des 	onglets, des modules de news, une zone de commentaires …</li>
<li><code>aside</code>, 	<code>footer</code> et <code>header</code> peuvent être utilisées pour marquer des zones particulières dans 	les sections que nous venons de voir : un groupe de titres pour 	<code>header</code>, des 	métadonnées (<em>copyright</em>, auteur, référence…) pour le <code>footer</code> et des informations complémentaires pour <code>aside</code> (autres articles, produits similaires&#8230;)</li>
<li>La <code>div</code> reste d&rsquo;actualité pour tous les besoins non couverts</li>
</ul>
<p>Citons également:</p>
<ul>
<li>la balise <code>nav</code> qui marque les liens de navigation de la page (et non d&rsquo;une <code>section</code>, 	<code>footer</code> étant plus 	indiqué pour cela),</li>
<li><code>time</code> qui permet de marquer de manière formelle une date (exemple PHP : 	<code>&lt;time datetime="&lt;?= 	date( DATE_W3C); ?&gt;"&gt;Maintenant !&lt;/time&gt;</code>).</li>
<li><code>figure</code> et <code>figcaption</code> pour les illustrations et leur description (regardez le code source de cet article)</li>
</ul>
<p>On le voit, ces nouvelles balises peuvent être mises à profit principalement pour les sites à contenu éditorial (journaux, réseaux sociaux&#8230;) voire les sites de e-commerce. Le problème que vous rencontrerez sera que dans les anciennes version d&rsquo;Internet Explorer vous ne pourrez pas appliquer de style à ces éléments (mettre un <code>display:block</code> sur les balises sectionnantes par exemple). Pour cela il suffit d&rsquo;un court fix Javascript que vous pourrez trouver sur le net en tapant <em>HTML5 shiv</em>.</p>
<h3>microdata</h3>
<p>Microdata, présenté plus en détails ailleurs dans ce numéro (NDR : le numéro en question étant payant, je vous propose d&rsquo;aller directement sur <a href="http://schema.org/docs/gs.html#microdata_why">le site édité par Google</a>), se propose de remplacer RDFa et microformat. Si vous ne connaissez pas ces projets, il s&rsquo;agit simplement de marquer sa page d&rsquo;une manière beaucoup plus précise et libre que ce que la spécification HTML5 peut prévoir. Si par exemple votre site liste des événements, des recettes de cuisine, des personnes ou des avis vous allez pouvoir indiquer très précisément dans votre page où se trouvent les informations intéressantes. Concrètement vous pouvez définir vos propres vocabulaires ou vous rendre sur <a href="http://schema.org">http://schema.org</a> (maintenu par Google, Bing et Yahoo!) et choisir le vocabulaire adapté à ce que vous voulez décrire. Puis à l&rsquo;aide de 3 attributs (<code>itemscope</code>, <code>itemtype</code> et <code>itemprop</code>), vous marquez les éléments importants. Par exemple nous allons marquer précisément une page présentant un profil. On commence par marquer la zone avec <code>itemscope</code> :</p>
<pre><code>&lt;div itemscope&gt;../..
&lt;/div&gt;</code></pre>
<p>On déclare ensuite le vocabulaire auquel on va se référer grâce à <code>itemtype</code> et une <abbr>URL</abbr>. Ici on va prendre le format <code>hCard</code>, probablement le plus répandu des formats. Notez que l&rsquo;url pointe sur le site microformats : microformat et microdata sont compatibles car définir un vocabulaire ne consiste jamais qu&rsquo;à lister des clés et leurs valeurs possibles.</p>
<pre><code>&lt;div itemscope itemtype="http://microformats.org/profile/hcard"&gt;
../..
&lt;/div&gt;
</code></pre>
<p>Enfin avec <code>itemprop</code> vous marquez chaque information de votre markup pour indiquer où se trouve la valeur de chaque partie du vocabulaire.</p>
<figure>
<pre><code>&lt;div itemscope itemtype="http://microformats.org/profile/hcard"&gt;
Vous pouvez contacter &lt;span itemprop="given-name"&gt;JP Vincent&lt;/span&gt; 
pour toute question HTML5 sur 
&lt;a itemprop="email" href="mailto:jp@braincracking.org"&gt;ce mail&lt;/a&gt;
../..
&lt;/div&gt;
</code></pre>
<figcaption>marquage d&rsquo;une page de contact avec le standard microdata et un vocabulaire microformat</figcaption>
</figure>
<p>Un programme tel que ceux de Google ou certains plugins navigateur vont lire le markup et associer le nom avec le mail.&nbsp;</p>
<h3>ARIA</h3>
<p>ARIA est une spécification axée sur l&rsquo;accessibilité et permet de proposer des interfaces riches  qui restent accessibles aux utilisateurs de technologie d&rsquo;assistance. A son niveau le plus basique vous pouvez au moins indiquer les zones principales grâce à l&rsquo;attribut <code>role</code>: les liens de navigations avec <code>role="navigation"</code>, le contenu principal avec <code>role="main"</code>, les mentions légales avec <code>role="contentinfo"</code>, le titre ou le logo avec <code>role="banner"</code>&hellip;</p>
<p>A un niveau un peu plus évolué, vous pouvez marquer des interactions plus complexes et néanmoins répandues comme des barres de progression (<code>role="progressbar"</code>), des curseurs (<code>role="scrollbar"</code>, <code>role="slider"</code>), des menus, des boîtes de dialogue (<code>role="dialog"</code>). C&rsquo;est très utile aux technologies d&rsquo;assistance pour comprendre des zones de l&rsquo;écran qui sont plus dynamiques que jamais : imaginez que vous ayez un chat en ligne en Web, comme dans l&rsquo;exemple suivant.</p>
<figure>
<pre><code>&lt;ol&gt;
	&lt;li&gt;KevinDu75: Kikoo ^__^
&lt;/ol&gt;
</code></pre>
<figcaption>Markup d&rsquo;une chatroom</figcaption>
</figure>
<p>Sans indication particulière, un lecteur d&rsquo;écran va lire une seule fois ce code, alors qu&rsquo;il y a sûrement une routine JavaScript qui met à jour régulièrement cette zone. Avec ARIA, il suffit de rajouter le rôle correspondant (d&rsquo;après la spécification, c&rsquo;est <code>log</code>) à cette fonctionnalité classique, et les lecteurs se mettront à lire automatiquement tout dernier élément ajouté au DOM</p>
<figure>
<pre><code>&lt;ol role="log"&gt;
	&lt;li&gt;KevinDu75: Kikoo ^__^
	&lt;li&gt;DarkBlackWarrior666 : LOL !!!!!
&lt;/ol&gt;
</code></pre>
<figcaption>Marquage ARIA de la zone de chat</figcaption>
</figure>
<p>La bonne nouvelle c&rsquo;est que certaines librairies JavaScript y compris certains plugins jQuery rajoutent automatiquement des attributs ARIA lorsqu&rsquo;ils vous proposent des widgets un peu compliqués. C&rsquo;est à vous de faire attention à ce que l&rsquo;option soit bien proposée pour garantir une meilleure accessibilité de vos interfaces.</p>
<h2>Interaction utilisateur</h2>
<h3>Les nouveaux formulaires</h3>
<p>Les formulaires HTML ont été largement dépoussiérés.<br />
Auparavant on avait surtout des 	champs de type texte ou mot de passe. HTML5 définit une série de 	nouveaux types qui se rencontrent couramment sur les formulaires : 	<code>url</code>, <code>mail</code>, <code>search</code>, <code>date</code>, <code>number</code>&helip; Quel est l&rsquo;intérêt ? Il offre aux navigateurs et 	aux technologies d&rsquo;assistance des points d&rsquo;attache pour améliorer 	l&rsquo;expérience utilisateur : changement de clavier virtuel sur les 	mobiles pour faciliter la saisie, apparition d&rsquo;interfaces 	spécialisées pour sélectionner facilement des dates ou des 	chiffres …<br />
<div id="attachment_926" class="wp-caption aligncenter" style="width: 248px"><img class="size-full" src="http://94.23.51.58/jpvincent/blog/wp-content/uploads/2012/01/html5_intro_figure_04.png" alt="" /><img class="size-full wp-image-926" title="type_date" src="http://94.23.51.58/jpvincent/blog/wp-content/uploads/2012/01/html5_intro_figure_03.png" alt="" width="238" height="208" /><p class="wp-caption-text">les adaptations des navigateurs aux champs date et tel</p></div><br />
La  validation 	des données a été standardisée. Jusqu&rsquo;ici les développeurs empilaient une bonne 	couche de Javascript par dessus chaque formulaire. Ici simplement 	avec du HTML vous pouvez demander au navigateur d&rsquo;exécuter un 	certain nombre de règles de validation et d&rsquo;afficher des 	indications à l&rsquo;utilisateur pour remplir sans se tromper son 	formulaire.<br />
La simplification de certains 	comportements jusqu&rsquo;ici scriptés : mettre le <em>caret </em>automatiquement sur certains formulaires avec l&rsquo;attribut 	<code>autofocus</code>, mettre un 	texte de suggestion par défaut dans les champs texte qui apparaît 	ou disparaît avec <code>placeholder</code>.</p>
<p>Pour le développeur Web coincé entre PHP et JavaScript il y a ici une vraie opportunité : la validation des données doit bien sur rester côté serveur, et il y a maintenant une manière très simple de réutiliser le même code entre le client et le serveur. Prenons une classe de validation en PHP simpliste que l&rsquo;on voudrait utiliser, comme ci-après.</p>
<figure>
<pre><code>&lt;?php
class validation {
	// d'abord on met public l'expression rationnelle pour l'utiliser plus tard
	public static $regMail="^[w-]+(?:.[w-]+)*@(?:[w-]+.)+[a-zA-Z]{2,7}$";
	public static $regNickname="#^[a-zA-Z0-9àáâãäåèéêëìíîïòóôõöùúûüýýÿçñ _-.']{2,50}$#i";
	// fonctions appellées par le serveur
	static function isValidMail( $email ) {
		return preg_match("/".self::$regMail."/",$email));
	}
	static function isValidNickname( $nickname ) {
		return preg_match("/".self::$regNickname ."/",$nickname));
	}
}
</pre>
<p></code></p>
<figcaption>une classe statique PHP de validation des données</figcaption>
</figure>
<p>On voit dans le listing 4 que l'on a isolé les expressions régulières utilisées pour valider le formulaire dans des variables statiques, et nous allons en fait les réutiliser dans le HTML. En HTML5 nous avons l'attribut <code>pattern</code> pour donner des expressions régulières au navigateur qu'il va exécuter pour vérifier l'entrée utilisateur, comme ci-après.</p>
<figure>
<pre><code>&lt;form&gt;
	&lt;label &gt;Votre mail : &lt;input type="email" pattern="&lt;?= validation:: $regMail ?&gt;" required /&gt;
	&lt;/label&gt;
	&lt;label &gt;Votre surnom : &lt;input type="text" pattern="&lt;?= validation:: $regNickname ?"&gt; required /&gt;
	&lt;/label&gt;
&lt;/form&gt;
</pre>
<p></code></p>
<figcaption>Transmission des expressions régulières de validation au navigateur</figcaption>
</figure>
<div id="attachment_928" class="wp-caption aligncenter" style="width: 244px"><a href="http://94.23.51.58/jpvincent/blog/wp-content/uploads/2012/01/html5_intro_figure_05.png"><img class="size-full wp-image-928" title="html5_intro_figure_05" src="http://94.23.51.58/jpvincent/blog/wp-content/uploads/2012/01/html5_intro_figure_05.png" alt="" width="234" height="93" /></a><p class="wp-caption-text">interface de validation de formulaire, sous Chrome</p></div>
<p>Sans avoir tapé de CSS ou de javascript, certains navigateurs afficheront l'équivalent de la figure 5 à l'utilisateur. Vous trouverez quelques librairies Javascript qui permettent d'émuler la même chose sur tous les navigateurs.</p>
<h3>vidéo native</h3>
<p>Les balises <code>audio</code> et <code>video</code> ont été calquées sur le modèle de la balise <code>img</code> : permettre très simplement d'insérer du multimédia dans une  page Web. La promesse est bien sur de se passer de Flash pour lire de la vidéo, et d'offrir à vos utilisateurs plus de fluidité (pas de démarrage de Flash ou d'un autre plugin), une meilleure utilisation du CPU sur les environnements que Flash n'adressait pas (Mac OS, Linux, les mobiles) et une interface par défaut qu'ils connaissent déjà. Pour le développeur, pouvoir utiliser JavaScript et CSS pour contrôler une vidéo est très naturel et promet donc de belles intégrations.</p>
<p>Tempérons cela par plusieurs points :</p>
<ul>
<li>les implémentations actuelles 	des navigateurs sont encore un cran en dessous de ce que permet 	Flash. Notoirement mettre une interface en CSS en vrai plein écran 	n'est encore possible sur aucun navigateur, il faut pour cela 	attendre une autre spécification : la <em>Fullscreen API</em>, en cours de 	test chez Firefox et Chrome</li>
<li>la guerre des codecs continue de 	faire rage : le standard de l'industrie vidéo est h.264 et ils 	n'ont aucune envie d'adapter tous les outils de leur chaîne de 	production pour le Web. De l'autre côté WebM, pourtant offert à 	la communauté par Google, ne peut être décodé que sur Firefox, 	Chrome et Opéra et on attend depuis un an qu'Adobe fasse de même 	pour que les sites Web n'aient pas à stocker en deux encodages 	leurs vidéos.</li>
<li>le W3C n'a pas l'intention 	d'adresser le marché particulier du <em>streaming </em>payant ou des 	vidéos protégées, car c'est contraire à la philosophie 	d'ouverture du Web. Cela signifie que pour ces marchés Flash 	restera très longtemps la seule technologie utilisable.</li>
</ul>
<p>En bref, les éléments multimédia sont déjà indispensables sur des environnements où Flash n'est pas présent, et vous pouvez déjà essayer de l'intégrer en complément de Flash sur vos sites Web, mais il est peu probable que ce soit votre seul lecteur.</p>
<h3>Géolocalisation</h3>
<p>La géolocalisation permet à une page Web de savoir (après autorisation de l'utilisateur) où celui-ci se trouve. Au contraire de la géolocalisation par IP qui peut au mieux vous donner le nom de la ville de votre point d'entrée sur le Net (en ADSL, cela peut être une erreur de 5 kms), les implémentations navigateur se basent sur des données matérielles plus précises :</p>
<ul>
<li>sur bureau, l'adresse MAC de la 	carte Wifi est envoyée sur les systèmes de Google (pour Firefox, 	Opéra et Chrome) ou de Microsoft, qui ont scanné à grande échelle 	les zones les plus densément peuplées, et qui y ont associé des 	coordonnées GPS. En gros, si la « streetview » de 	Google Maps ou de Bing est disponible pour votre quartier, vous 	serez repéré précisément (de l'ordre de la centaine de mètres)</li>
<li>sur mobile, c'est le GPS embarqué 	qui est directement interrogé. A défaut de GPS, c'est la 	triangulation par antenne relai.</li>
</ul>
<p>Dans tous les cas si aucune donnée n'est disponible, c'est au final l'adresse IP qui est utilisée, avec l'imprécision que l'on sait.</p>
<p>Voici un exemple d'implémentation qui essaye d'utiliser l'API du navigateur, mais qui à défaut va utiliser les solutions traditionnelles de détection par IP :</p>
<figure>
<pre><code>// test du support navigateur
if( navigator.geolocation ) {
	// appel asynchrone à l'API
	navigator.geolocation.getCurrentPosition( function( position ) {
	// l'objet position un sous-objet contient toutes les informations
		console.log( position.coords.latitude,  position.coords.longitude );
	});
} else {
	// retour à une solution moins précise
	var oXHR = new XMLHTTPRequest();
	// appel d'un script PHP qui va récupérer l'IP et trouver la ville
	oXHR.open('GET', '/getlocation.php');
	// on peut supposer que le script répond avec des coordonnées
	oXHR.onload = function( e ) {
		console.log( e.currentTarget.responseText );
	};
	oXHR.send();
}
</pre>
<p></code></p>
<figcaption>Géolocalisation native, avec méthode de secours traditionnelle</figcaption>
</figure>
<p>Les solutions de correspondance IP / ville sont généralement payantes, même si il en existe des gratuites. Elle se présentent sous la forme de script et de base de données à installer chez soi et à exploiter en PHP. Dans l'un ou l'autre cas vous n'êtes bien sur absolument pas certain de la véracité des données. La géolocalisation des navigateurs permet à tout le moins d'avoir une solution IP gratuite, et dans la plupart des cas d'obtenir des informations beaucoup plus précises.</p>
<p>L'API prévoit aussi de demander des coordonnées plus précises, de pouvoir surveiller les déplacements et de fournir des données de vitesse, d'altitude, d'orientation par rapport au nord. Certaines implémentations peuvent également y rajouter la ville ou l'adresse !</p>
<p>Le fait que géolocalisation existe, et marche depuis déjà deux ans est majeur pour les technologies du Web, car c'est la première fois qu'une page Web peut interagir avec le matériel de l'utilisateur, privilège réservé jusqu'ici aux applications natives.</p>
<h2>L'ère des applications Web</h2>
<h3>Websocket et Server Sent Events</h3>
<p>WebSocket implémente ce que les développeurs Web devaient jusque là simuler : de la communication temps réel bi-directionnelle entre le client et le serveur. Le protocole HTTP montre en effet ses limites lorsqu'il s'agit d'attendre des informations venant du serveur ou d'écrire un jeu vidéo avec un flux d'informations continu client / serveur. Chaque envoi d'information est encapsulé par parfois plusieurs ko de headers tandis qu'avec websocket il ne s'agit plus que de quelques octect superflus. De plus la connection reste ouverte en permanence ce qui réduit très fortement la latence, chose indispensable pour des applications aussi réactives que des jeux. Il y a un article dans ce numéro qui trait plus en profondeur de WebSocket</p>
<p>Le problème de WebSocket pour le développeur PHP, c'est que cela remet en cause beaucoup de choses côté serveur : les serveurs WebSocket d'aujourd'hui sont écrits dans des langages tels que JavaScript (sur serveur Node.js) qui sont taillés pour exécuter du code de manière asynchrone et qui supportent en théorie des milliers de connexions ouvertes simultanément. Il existe bien une implémentation WebSocket en PHP, mais on ne sait pas vraiment quelle charge elle peut tenir en production, l'empreinte mémoire et la consommation CPU d'un processus PHP étant généralement assez gourmande : après tout pour tenir un socket ouvert, il n'y a pas d'autre moyen qu'une boucle infinie entrecoupée de <code>sleep()</code> et PHP n'a pas été pensé dans ce sens !</p>
<p>A côté de WebSocket, il y a la spécification « Server Sent Events », qui elle ne permet d'avoir que la communication du serveur au client, ce qui peut suffire à la plupart des applications : surveiller un flux twitter, un cours boursier, avoir un dashboard etc … Pour envoyer des informations au serveur, il reste bien sur <code>XMLHTTPRequest</code>, qui est un peu plus lent que WebSocket et qui crée un nouveau thread sur le serveur. En fait SSE remplace efficacement et formalise la technique dite « forever iframe » où PHP et JavaScript gardaient la connexion ouverte via une <code>iframe</code> où du HTML était régulièrement injecté, même lorsqu'aucun événement ne devait être envoyé.</p>
<p>L'avantage de Server Sent Events, c'est qu'elle permet de réutiliser pratiquement le même code côté PHP, avec quelques ajouts que nous allons commenter, tout en optimisant le trafic réseau et en formalisant les échanges de données. Regardons d'abord comment on faisait en PHP pour maintenir la connexion ouverte par une iframe :</p>
<figure>
<pre><code>&lt;?php
// désactivation des caches navigateurs et proxys
header('Cache-Control: no-cache');
// boucle infinie
while(true) {
	// méthode métier de récupération des données
	$data = my_get_data();
	// encodage en JSON pour interprétation directe en JavaScript
	$data = json_encode( $data );
	// on fait exécuter une fonction JavaScript qui contient nos données
	print '&lt;script&gt; fonction_rappel('. $data .'); &lt;/script&gt;';
	// même si les données sont vides, la connexion est maintenue car du HTML est envoyé
	flush();
	// on laisse respirer le CPU avant la prochaine itération
	sleep(1);
}
</pre>
<p></code></p>
<figcaption>technique de <em>forever iframe</em>, côté PHP</figcaption>
</figure>
<p>Voici maintenant les lignes que nous devrions ajouter pour renvoyer des informations à un navigateur supportant SSE :</p>
<figure>
<pre><code>&lt;?php
// détection du support par le navigateur
<strong>$hasSSE = ($_SERVER['HTTP_ACCEPT'] === 'text/event-stream');</strong>
// désactivation des caches navigateurs et proxys
header('Cache-Control: no-cache');
// on informe le navigateur qu'on va lui répondre au format SSE
if( $hasSSE === true)
	<strong>header('Content-Type: text/event-stream');</strong>
// boucle infinie
while(true) {
	// méthode métier de récupération des données
	$data = my_get_data();
	// encodage en JSON pour interprétation directe en JavaScript
	$data = json_encode( $data );
	if( $hasSSE === true)
		// le standard prévoit que les données arrivent après la chaîne data:
		<strong>print 'data: '. $data;</strong>
	else
		// on fait exécuter une fonction JavaScript qui contient nos données
		print '&lt;script&gt; fonction_rappel('. $data .'); &lt;/script&gt;';

	// le standard sépare les données sur plusieurs lignes par un double retour chariot
	<strong>print PHP_EOL.PHP_EOL;</strong>
	flush();
	sleep(1);
}
</pre>
<p></code></p>
<figcaption>Ajout du code pour supporter Server Sent Event</figcaption>
</figure>
<p>On le voit, on envoie simplement un entête supplémentaire, puis chaque ligne de donnée est préfixée par <span style="text-decoration: underline;">data:</span> (avec ou sans espace), et les blocs de données sont séparées par un <strong>double retour chariot</strong>.</p>
<p>Côté client il suffit d'instancier l'objet <code>EventSource</code> avec l'URL du serveur et d'écouter les événements, comme ici :</p>
<figure>
<pre><code>// on se branche sur le PHP
var connexion = new EventSource('/get_data.php');
// programmation événementielle
connexion.onmessage = function( e ) {
	// la propriété data de l'événement contient directement la chaîne JSON qu'on a créé en PHP
	console.log( e.data );
};
</pre>
<p></code></p>
<figcaption>Utilisation côté client de Server Sent Event</figcaption>
</figure>
<p>L'API va beaucoup plus loin et en plus de la reconnexion automatique gère également :</p>
<ul>
<li>les tickets, généralement un 	marqueur de temps ou un numéro de ligne qui peut servir de repère 	à PHP lorsque le navigateur se reconnecte,</li>
<li>des événements nommés, qui 	permettent de créer des catégories de dialogue,</li>
<li>des événements comme les 	erreurs, l'ouverture et la fermeture de la connexion</li>
</ul>
<p>Il existe d'hors et déjà des librairies JavaScript permettant de simuler l'API Server Sent Events sur tous les navigateurs, et donc de réutiliser votre code PHP.</p>
<h3>Offline</h3>
<p>De plus en plus d'utilisateurs sont en situation de mobilité lorsqu'ils consultent des sites Web, qu'ils soient sur smartphone ou qu'ils utilisent un laptop dans un café avec une connexion Wifi défectueuse ou inexistante. Le grand avantage qu'ont les applications dites natives, c'est que l'interface se lance immédiatement, qu'il y ait du réseau ou pas. Hors certaines applications Web comme les jeux <em>casual</em> n'ont parfois pas du tout besoin de connexion, tandis que d'autres comme les webmails n'ont besoin d'une connexion que pour aller chercher de nouvelles données.</p>
<p>La gestion de l'offline vise à mettre les applications Web au même niveau que les applications natives en :</p>
<ul>
<li>ne faisant télécharger qu'une fois pour 	toute l'interface et le cœur applicatif,</li>
<li>donnant de 	quoi gérer les versions de l'application,</li>
<li>permettant de réagir et détecter les situations de déconnexion.</li>
</ul>
<p>Concrètement vous allez référencer un fichier <code>.manifest</code> dans votre HTML :</p>
<pre><code>&lt;!doctype html&gt;
&lt;html manifest="mapage.manifest"&gt;
…
</code></pre>
<p>Puis vous allez servir ce fichier (avec un entête type mime "<code>text/manifest</code>") qui référence plusieurs choses :</p>
<ul>
<li>les dépendance (CSS, JS, 	images..) à garder pour une utilisation <em>offline</em> (section 	<code>CACHE</code>) ,</li>
<li>les URLs qui doivent absolument 	accéder au réseau (section <code>NETWORK</code>),</li>
<li>les pages par défaut lorsque le 	réseau ne répond pas (section <code>FALLBACK</code>)</li>
</ul>
<p>L'exemple suivant serait une application Web qui n'aurait que deux dépendances, qui irait chercher le reste sur le réseau, et qui affiche la page <code>offline.html</code> pour toute autre requête sans réseau :</p>
<figure>
<pre><code>CACHE MANIFEST
# v1.0

CACHE
css/styles.css
js/main.js

FALLBACK:
/ offline.html

NETWORK:
*
</pre>
<p></code></p>
<figcaption>fichier <code>offline.manifest</code></figcaption>
</figure>
<p>La déclaration est simple, c'est dans la programmation métier de votre application que les choses se compliquent. Par défaut les navigateurs vont donc afficher la version qu'ils ont en local, puis aller vérifier si le manifeste de cache a changé ne serait ce que d'un octet (c'est pour cela qu'on met généralement en commentaire le numéro de version de l'application). Si c'est le cas, il va télécharger de manière transparente toutes les ressources, qu'elles aient changé ou non, et envoyer un événement Javascript pour dire qu'il a mis à jour le cœur applicatif. Il appartient au développeur de gérer ces états de transition entre deux versions de la même application. Il peut être aidé en cela par une série d'événement JavaScript et de fonctions situées dans l'objet global <code>applicationCache</code>, et qui lui donneront l'état de la mise à jour et un contrôle sur celle ci.</p>
<p>Notons par ailleurs que l'on a accès à la propriété <code>window.navigator.onLine</code> (valeur booléenne), censée donner l'état de la connexion, et aux événements <code>ononline </code>et <code>onoffline</code>, qui avertissent du changement d'état. Malheureusement seul Internet Explorer, et encore à partir de la version 8, implémente de manière utile cette propriété et ces événements.</p>
<h3>XHR 2</h3>
<p><code>XMLHTTPRequest</code> a été la base technique à ce que l'on a appelé le « Web 2.0 » et permet de faire des requêtes asynchrones au serveur pour récupérer ou envoyer des informations. Dans HTML5, la version 2 déjà implémentée dans la plupart des navigateurs donne plus de contrôle et d'informations sur les requêtes :</p>
<ul>
<li>indications de progression : si 	la taille totale de votre envoi de fichier ou de votre 	téléchargement est connue, vous avez accès à l’évènement <code>progress</code>, et aux 	propriétés <code>total</code> et 	<code>loaded</code>. Vous pouvez 	maintenant afficher à votre utilisateur de vraies barres de 	progression.</li>
<li>création de formulaires à la 	volée : l'API <code>FormData</code> permet de créer ou de modifier des formulaires à la volée et 	le navigateur les formate en mode <code>POST</code>. 	Ceci permet de gérer facilement l'envoi de fichiers envoyés en 	<em>drag and drop</em> depuis le bureau ou en sélection multiple, le 	tout sans rechargement de page</li>
</ul>
<p>En bref, là aussi cette API modernise les applications Web en faisant évoluer un des outils principaux des développeurs.</p>
<h3>Local Storage</h3>
<p>Que l'on gère un site Web classique avec des formulaires sur plusieurs pages ou une application Web lourde type google Docs, on a besoin de stocker les informations que l'utilisateur génère, sans forcément passer par le réseau pour stocker ces informations sur le serveur. On pouvait jusqu'ici utiliser les cookies, mais on était limité en taille (4ko tout compris) et on pouvait dégrader sérieusement les performances : sur la plupart des sites les cookies sont envoyés avec chaque requête HTTP et une page Web moyenne est composée de 80 requêtes HTTP, soit un trafic réseau énorme et surtout inutile. La solution préconisée par PHP est d'ailleurs de ne stocker dans le cookie qu'un court identifiant de session, pour retrouver côté serveur les données.</p>
<p>« Web Storage » permet soit de faire tampon, soit d'éviter carrément le trafic réseau ou la gestion de session en offrant aux développeurs un espace pour stocker au moins 5 Mo de données. Utilisez l'API <code>sessionStorage</code> pour un stockage temporaire (vidé à la fermeture de la page) ou <code>localStorage</code> pour un stockage permanent. Dans les deux cas vous pouvez stocker des paires clé/valeur très simplement :</p>
<figure>
<pre><code>localStorage.setItem('locale', 'fr_FR');
console.log( localStorage.getItem('locale') );
localStorage.removeItem( 'locale');
</pre>
<p></code></p>
<figcaption>définir, récupérer et supprimer une valeur côté client</figcaption>
</figure>
<p>Seules les chaînes de caractère sont acceptées, donc si vous avez besoin de stocker des données plus structurées, utilisez simplement JSON. Si vous avez besoin d'utiliser cette fonctionnalité sur tous les navigateurs, sachez que vous pouvez utiliser Flash ou des techniques propriétaires de chez Microsoft pour y stocker jusqu'à 100ko de données. Il existe déjà plusieurs petites librairies qui font cette abstraction pour vous.</p>
<h2>Le futur</h2>
<p>Les navigateurs veulent clairement concurrencer les applications dites natives, voici ce sur quoi ils planchent.</p>
<p><strong>La 3D </strong>: avec WebGL, qui permet donc de faire des jeux ou des environnements immersifs le tout en 3D. L'interaction avec le DOM permet même de réutiliser d'autres composants : on peut par exemple utiliser en texture un élément <code>&lt;video&gt;</code> ou le contenu d'une <code>&lt;div&gt;</code> sur des éléments de décor. Certaines sociétés éditrices de jeux vidéos console ou PC travaillent déjà sur cette techno pour trouver de nouveaux canaux de distribution et toucher plus de monde, en pariant sur une plus large diffusion des navigateurs et sur l'accélération matérielle généralisée d'ici 2 à 3 ans.</p>
<p><strong>Le multithread </strong>: la spécification <code>Web Workers</code> permet d'exécuter du javascript dans un processus différent du navigateur, et même d'exploiter un second processeur. Cela permet d'avoir des applications avec des calculs lourds telles de la manipulation de photo ou de vidéo, des jeux vidéo ou des applications scientifiques.</p>
<p><strong>L'accès au matériel</strong> : la géolocalisation permet déjà d'accéder au GPS des mobiles, <code>getUserMedia</code> permet d'accéder à la caméra, et <code>DeviceOrientation</code> pointe sur les informations du gyroscope. Il y a déjà des implémentations sur Firefox, Chrome et certains mobiles.</p>
<p><strong>Le peer to peer </strong>: des expérimentations ont été menées et permettent de faire dialoguer directement deux navigateurs de deux machines différentes sans passer par un serveur pour maintenir la connexion. Oui le prochain Skype pourrait être écrit en JavaScript.</p>
<p><strong>L'accès au bureau </strong>: plein écran, notifications, contacts … il y a plusieurs expérimentations autour de ces fonctionnalités qui vont permettre aux pages, pardon aux applications Web de s'intégrer complètement à votre OS, que vous soyez sur mobile ou sur PC classique.</p>
<p>Et je n'ai listé ici que les API qui ont au moins une implémentation, fusse-t-elle expérimentale. L'idée vous l'aurez compris est de donner les pleins pouvoirs aux « sites » Web qui sont aujourd'hui les interfaces privilégiées par le grand public. Cela ne se fait pas sans soulever des questions sur la sécurité, mais le W3C veille et chaque API est prévue pour passer par une demande de permission à l'utilisateur.</p>
<h2>Conclusion</h2>
<p>HTML5 et les navigateurs apportent toutes ces nouvelles capacités qui rivalisent avec les applications natives. Avec la puissance de diffusion du Web qui est de fait multi-plateforme, HTML5 termine le travail commencé par PHP et Linux car les logiciels de demain pourront être écrits avec des langages non propriétaires. C'est une grande victoire pour le monde du libre.</p>
<p>Références :</p>
<h3>Sur Internet</h3>
<ul>
<li><em>http://braincracking.org/</em> – [FR] le site de l'auteur : veille technologique sur HTML5, 	Javascript et les performances Web,</li>
<li><em>http://livre-html5.com/</em> – [FR] le site du livre HTML5, avec les démos,</li>
<li><a href="http://www.html5-css3.fr/"><em>http://html5-css3.fr/</em></a> – [FR] formation et tutoriaux à HTML5 et CSS3,</li>
<li><a href="http://alsacreations.com/"><em>http://alsacreations.com/</em></a> – [FR] tutoriaux, forums et actualité des technos frontend,</li>
<li><em><a href="http://html5doctor.com/">http://html5doctor.com/</a> </em>– [EN] site d'information sur la sémantique de HTML5,</li>
<li>http://www.html5rocks.com/<em> </em>– [EN] maintenu par Google : tutoriaux et présentation 	générale avec démos de HTML5 au sens large.</li>
</ul>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/braincracking?a=ao2sNdxi0BI:3riAfbrYUis:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/braincracking?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=ao2sNdxi0BI:3riAfbrYUis:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/braincracking?i=ao2sNdxi0BI:3riAfbrYUis:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=ao2sNdxi0BI:3riAfbrYUis:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/braincracking?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=ao2sNdxi0BI:3riAfbrYUis:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/braincracking?i=ao2sNdxi0BI:3riAfbrYUis:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=ao2sNdxi0BI:3riAfbrYUis:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/braincracking?i=ao2sNdxi0BI:3riAfbrYUis:V_sGLiPBpWU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/braincracking/~4/ao2sNdxi0BI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://braincracking.org/2012/02/01/html5-aujourdhui/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://braincracking.org/2012/02/01/html5-aujourdhui/</feedburner:origLink></item>
		<item>
		<title>Usage avancé des fonctions JavaScript</title>
		<link>http://feedproxy.google.com/~r/braincracking/~3/YITLQ7NauNA/</link>
		<comments>http://braincracking.org/2011/11/17/usage-avance-des-fonctions-javascript/#comments</comments>
		<pubDate>Thu, 17 Nov 2011 11:00:37 +0000</pubDate>
		<dc:creator>jpvincent</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[orienté objet]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://braincracking.org/?p=896</guid>
		<description><![CDATA[Cet article est un complément à l&#8217;article sur les 3 fondamentaux de JavaScript, il vaut mieux être déjà à l&#8217;aise avec JavaScript avant de crier au scandale en voyant ce qu&#8217;on peut en faire. Pour reprendre un bon mot de quelqu&#8217;un qui avait assisté à ma conférence sur JavaScript : Admettons donc que vous ayez [...]]]></description>
			<content:encoded><![CDATA[<p>Cet article est un complément à l&rsquo;article sur <a href="http://braincracking.org/?p=883">les 3 fondamentaux de JavaScript</a>, il vaut mieux être déjà à l&rsquo;aise avec JavaScript avant de crier au scandale en voyant ce qu&rsquo;on peut en faire. Pour reprendre un bon mot de quelqu&rsquo;un qui avait assisté à ma <a href="http://www.slideshare.net/jpvincent/javascript-fondamentaux-et-oop">conférence sur JavaScript</a> :</p>
<div id="attachment_897" class="wp-caption aligncenter" style="width: 552px"><a href="https://twitter.com/#!/pierreca/status/134629949985398785"><img class="size-full wp-image-897  " title="pornstar" src="http://94.23.51.58/jpvincent/blog/wp-content/uploads/2011/11/pornstar.png" alt="" width="542" height="214" /></a><p class="wp-caption-text">javascript == la pornstar des langages de dev: souple, puissant, tu lui fait faire ce que tu veux, et ça peut finir bien crade.</p></div>
<p>Admettons donc que vous ayez digéré sans problème les portées et les fonctions, passons à deux choses vraiment particulières à JavaScript :</p>
<ol>
<li>le renvoi de fonction qui permet de belles optimisations et qui ouvre la voie à des patterns que les amoureux de la théorie du langage apprécieront,</li>
<li>une implémentation de <strong>classe statique</strong>, pour reprendre le terme utilisé en PHP ou en Java.</li>
</ol>
<p>Et enfin nous verrons une proposition d&rsquo;implémentation de deux <em>design pattern</em> célèbres et particulièrement utiles en JavaScript : <em>Singleton</em> et <em>Factory</em>.<br />
<span id="more-896"></span></p>
<h1>Classe statique</h1>
<p>Pour rappel, en PHP et dans d&rsquo;autres langages, une propriété ou une méthode statique peut être appelée sans que la classe n&rsquo;ait été instanciée pour créer un objet. C&rsquo;est généralement là que l&rsquo;on range les constantes ou les fonctions utilitaires par exemple. En JavaScript, tout étant objet y compris les fonctions, cela se fait assez naturellement :</p>
<pre><code>// constructeur
var <strong>myClass</strong> = function () { 
};
<strong>myClass.staticMethod</strong> = function() {
	console.log('OK');
};
// que voit on au niveau global ?
myClass.staticMethod(); // OK
</code></pre>
<p>Regardez la manière dont est définie <code>staticMethod</code> : on la range directement dans la fonction <code>myClass</code> ! Elle est donc directement disponible sans passer par la création d&rsquo;un objet. Comparons d&rsquo;ailleurs avec une définition de méthode d&rsquo;objet comme on l&rsquo;a vu dans les paragraphes précédents pour bien comprendre où sont disponibles ces nouvelles méthodes de classe.</p>
<pre><code>// constructeur
var myClass = function () { 
	return { 
		publicMethod:function() {
			console.log('OK');
		}
	}
};
myClass.staticMethod = function() {
	console.log('OK');
};

// que voit on au niveau global ?
myClass.publicMethod(); // Error
myClass.staticMethod(); // OK

// que voit l'instance ?
myObject = myClass(); 
myObject.publicMethod(); // OK
myObject.staticMethod(); // Error 
</code></pre>
<p>Si vous exécutez ce code dans votre console, vous allez voir où se produisent les erreurs :</p>
<ul>
<li>vous ne pouvez pas accéder à <code>publicMethod</code> sans avoir d&rsquo;abord instancié <code>myClass</code>,</li>
<li>l&rsquo;instance de <code>myClass</code> ne contient pas <code>staticMethod</code> car celle ci est directement disponible à partir du nom de la classe.</li>
</ul>
<h1>Renvoi de fonction</h1>
<p>Une fonction peut se redéfinir elle même quand elle s&rsquo;exécute. Ca a l&rsquo;air sale dit comme ça, mais nous allons voir un cas concret où cela est bien utile. Imaginez que vous construisez une mini-librairie dont une des fonctions permet de se rattacher à un événement du DOM. Pour supporter tous les navigateurs, il y a deux méthodes aux noms distincts et aux arguments légèrement différents que vous pouvez encapsuler dans une fonction en faisant un simple <code>if</code>.</p>
<pre><code>var onDOMEvent =
	function( el, ev, callback) {
		// le monde de Microsoft
		<strong>if(document.body.attachEvent){</strong>
			el.attachEvent('on'+ev, callback);
		// le monde du W3C
		} else {
			el.addEventListener( ev, callback, false);
		}
	};
</code></pre>
<p>Cette fonction marche très bien, mais à chaque fois qu&rsquo;elle est exécutée, le test sur la condition aussi est exécutée. Si vous faîtes une librairie vous vous devez de ne pas ralentir les développeurs qui l&rsquo;utiliseraient. Hors cette fonction pourrait très bien être appelée des centaines de fois, exécutant ainsi inutilement du code. Pour optimiser cela, nous allons redéfinir la fonction à la volée lors de sa première exécution.</p>
<pre><code>var onDOMEvent =
function( ) {
	if(document.body.attachEvent) {
		<strong>return function</strong>(element, event, callback) {
			element.attachEvent('on'+ event, callback);
		};
	} else {
		<strong>return function</strong>(element, event, callback) {
			element.addEventListener( event, callback);
		};
	}
}<strong>()</strong>;
</code></pre>
<p>Comme vous le voyez :</p>
<ul>
<li>cette fonction est auto-exécutée grâce aux deux parenthèses finales, et n&rsquo;a plus besoin des arguments puisqu&rsquo;elle ne sera plus jamais exécutée après.</li>
<li>le <code>if</code> reste, mais il ne sera exécuté qu&rsquo;une seule fois.</li>
<li>la fonction <strong>renvoie des fonctions anonymes</strong> contenant les codes spécifiques au navigateur. Notez que ces fonctions attendent toujours les mêmes paramètres.</li>
<li>lorsque <code>onDOMEvent()</code> sera appelé, seul l&rsquo;un ou l&rsquo;autre corps de fonction sera exécuté, nous avons atteint notre objectif</li>
</ul>
<p>C&rsquo;est une technique d&rsquo;optimisation pas forcément évidente à intégrer mais qui donne de très bons résultats. Cela irait un peu trop loin pour cet article mais si vous avez l&rsquo;âme mathématique, cherchez donc sur le Web comment calculer la suite de Fibonacci en JavaScript, avec et sans &laquo;&nbsp;memoization&nbsp;&raquo; (<a href="http://fr.wikipedia.org/wiki/M%C3%A9moization">Wikipedia</a>). Vous pouvez également créer des fonctions spécialisées qui capturent certains paramètres pour vous éviter d&rsquo;avoir à les préciser à chaque fois, technique connue sous le nom de <em>currying</em> (voir ce <a href="http://ejohn.org/blog/partial-functions-in-javascript/">post de John Resig</a> à ce sujet).<br />
Autre cas concret d&rsquo;école d&rsquo;utilisation de cette technique. Partons du code suivant qui boucle sur un petit tableau d&rsquo;objet et qui rattache l&rsquo;événement <code>onload</code> à une fonction anonyme.</p>
<pre><code>var queries = [ new XHR('url1'), new XHR('url2'), new XHR('url3')];
for(var i = 0; i &lt; queries.length; i++) { 
	queries[i].onload = function() { 
		console.log( i ); // référence 
	}
} 
</code></pre>
<p>Observez bien la valeur de <code>i</code> : notre fonction anonyme crée une portée, le parseur javascript ne voit pas <code>i</code> dans cette fonction, il remonte donc d&rsquo;un niveau pour la trouver. Jusqu&rsquo;ici tout va bien notre variable est bien référencée. Pourtant lorsque l&rsquo;événement <code>onload</code> est appelé par le navigateur, nous avons une petite surprise:</p>
<pre><code>queries[ 0 ].onload(); // 3! 
queries[ 1 ].onload(); // 3! 
queries[ 2 ].onload(); // 3!</code></pre>
<p><code> </code><br />
L&rsquo;interpréteur JavaScript a correctement fait son boulot : la fonction <code>onload</code> voit bien <code>i</code> (sinon nous aurions eu <code>undefined</code>), mais c&rsquo;est une <strong>référence</strong> vers la variable, pas une copie de sa valeur ! Hors <code>onload</code> n&rsquo;est appelé qu&rsquo;après que la boucle se soit terminée, et <code>i</code> a été incrémentée entretemps. Pour fixer cela, nous allons utiliser deux choses :</p>
<ol>
<li>l&rsquo;auto-exécution, qui va nous permettre de copier la valeur de <code>i</code></li>
<li>le renvoi de fonction pour que <code>onload</code> soit toujours une fonction</li>
</ol>
<p>Attention, ça peut piquer les yeux :</p>
<pre><code>for(var i = 0; i &lt; queries.length; i++) { 
	queries[i].onload =  function(i) { 
		<strong>return function() { </strong>
			console.log( i ); // valeur 
		}; 
	}<strong>(i);</strong> // exécution immédiate 
} 
// plus tard ... 
queries[ 0 ].onload(); // 0 
queries[ 1 ].onload(); // 1 
queries[ 2 ].onload(); // 2
</code></pre>
<p>Essayez de suivre le chemin de l&rsquo;interpréteur :</p>
<ul>
<li><code>i</code> est donné à la fonction anonyme auto-exécutante</li>
<li>le paramètre de cette première fonction anonyme s&rsquo;appelle aussi <code>i</code> : dans cette portée locale, <code>i</code> a pour valeur 0 (pour la première passe)</li>
<li>la fonction renvoyée embarque toute la portée avec elle et n&rsquo;a donc que la <strong>valeur</strong> de ce nouveau <code>i</code>, qui ne bougera plus</li>
</ul>
<p>Pour info, ce cas d&rsquo;école est souvent posée lors des entretiens d&rsquo;embauche si on veut vérifier que vous avez bien compris les portées.</p>
<h1>Implémenter des design pattern</h1>
<p>En combinant namespace (voir l&rsquo;article <a href="http://braincracking.org/?p=89">JavaScript pour les développeurs PHP</a>), portée maîtrisée, espace privé et émulation d&rsquo;objets, nous allons implémenter le <em>design pattern Factory</em>. Factory ou Singleton sont très intéressants en JavaScript, notamment pour les <em>widgets</em> (type jQuery UI) : vous pouvez vous retrouver sur des pages où vous ne savez pas si le JavaScript d&rsquo;un Widget s&rsquo;est déjà exécuté sur tel élément du DOM. Pour optimiser, vous ne voulez pas recréer systématiquement le Widget mais plutôt <strong>créer une nouvelle instance ou récupérer l&rsquo;instance en cours</strong>. Vous avez donc besoin :</p>
<ol>
<li>d&rsquo;interdire la création directe d&rsquo;un objet</li>
<li>de passer par une fonction qui va faire la vérification pour vous et vous renvoyer une instance</li>
</ol>
<p>Commençons par créer notre espace de travail, ainsi que notre namespace:</p>
<pre><code>(function(){
// création ou récupération du namespace et du sous-namespace
MY = window.MY || {};
MY.utils = MY.utils || {};
// constructeur 
MY.utils.XHR=function( url ){
	console.log( url );
};
})();
</code></pre>
<p>A ce stade nous avonc une classe accessible de l&rsquo;extérieur avec <code>new MY.utils.XHR( url );</code>. C&rsquo;est bien mais pas top, nous voudrions passer par une fonction qui va vérifier s&rsquo;il n&rsquo;existe pas déjà une instance avec ce même paramètre URL. Nous allons déclencher une erreur en cas d&rsquo;appel direct (<a href="http://www.php.net/manual/fr/language.oop5.patterns.php#language.oop5.patterns.singleton">comme en PHP</a>) et prévoir une fonction <code>getInstance( url )</code> qui va se rattacher au namespace de la fonction constructeur.</p>
<pre><code>(function(){
// création ou récupération du namespace et du sous-namespace
MY = window.MY || {};
MY.utils = MY.utils || {};
// constructeur 
MY.utils.XHR=function( url ){
	<strong>throw new Error('please use MY.utils.XHR.getInstance()');</strong>
};
// factory
<strong>MY.utils.XHR.getInstance</strong> = function( url ) {
};
})();
</code></pre>
<p>Enfin nous allons introduire une variable privée qui va contenir la liste de nos instances (un objet <code>currentInstances</code> avec en index l&rsquo;url et en valeur l&rsquo;instance). Nous allons également rendre privé notre vrai constructeur.</p>
<pre><code>(function(){
// constructeur 
MY.utils.XHR=function( url ){
	throw new Error('please use MY.utils.XHR.getInstance()');
};

//constructeur privé
<strong>var XHR = function( url ){</strong>
	console.log( url );
};
// liste privée d'instances
<strong>var currentInstances = {};</strong>

// factory
MY.utils.XHR.getInstance = function( url ) {
	// déjà créé ? on renvoie l'instance
	if(currentInstances[url]) {
		return <strong>currentInstances[url]</strong>;
	// on crée, on enregistre, on renvoie
	} else {
		return currentInstances[url] = <strong>new XHR(url);</strong>
	}
};
})();
</code></pre>
<p>Telle quelle, cette implémentation permet déjà de créer une factory pour des objets qui ont besoin d&rsquo;être unique mais qui n&rsquo;ont qu&rsquo;un seul paramètre (<code>id</code> d&rsquo;un objet DOM, URL &#8230;). La vraie raison d&rsquo;être d&rsquo;une Factory, c&rsquo;est de gérer des objets complexes à instancier, à vous donc d&rsquo;étendre ses fonctionnalités. Les puristes auront remarqué que l&rsquo;objet renvoyé n&rsquo;était pas du type <code>MY.utils.XHR</code>, et qu&rsquo;on ne pouvait donc pas faire de vérification avec <code>instanceof</code> du type de l&rsquo;objet. Honnêtement je ne connais pas de bon moyen de le faire, à vous de voir si c&rsquo;est un manque dans votre code.<br />
Vous voilà paré à écrire du code un peu plus maintenable et mieux rangé, et vous pourrez crâner dans les dîners en ville en racontant vos exploits de codeur JS orienté objet.</p>
<h1>Conclusion</h1>
<ul>
<li>JavaScript a des concepts différents des langages majeurs et devient extrêmement important sur votre CV. Prenez le temps de l&rsquo;apprendre</li>
<li>Les librairies telles que jQuery ne sont pas faites pour couvrir les cas que nous venons de voir. jQuery permet d&rsquo;utiliser le DOM sereinement, pas d&rsquo;organiser votre code proprement.</li>
<li>J&rsquo;ai essayé d&rsquo;être pratique, mais lire un post de blog ne suffira jamais pour comprendre des concepts de programmation : codez !</li>
</ul>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/braincracking?a=YITLQ7NauNA:Z3du2fe4ocg:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/braincracking?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=YITLQ7NauNA:Z3du2fe4ocg:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/braincracking?i=YITLQ7NauNA:Z3du2fe4ocg:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=YITLQ7NauNA:Z3du2fe4ocg:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/braincracking?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=YITLQ7NauNA:Z3du2fe4ocg:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/braincracking?i=YITLQ7NauNA:Z3du2fe4ocg:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=YITLQ7NauNA:Z3du2fe4ocg:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/braincracking?i=YITLQ7NauNA:Z3du2fe4ocg:V_sGLiPBpWU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/braincracking/~4/YITLQ7NauNA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://braincracking.org/2011/11/17/usage-avance-des-fonctions-javascript/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		<feedburner:origLink>http://braincracking.org/2011/11/17/usage-avance-des-fonctions-javascript/</feedburner:origLink></item>
		<item>
		<title>JavaScript : 3 fondamentaux</title>
		<link>http://feedproxy.google.com/~r/braincracking/~3/LaZUIJNHUM0/</link>
		<comments>http://braincracking.org/2011/11/16/javascript-3-fondamentaux/#comments</comments>
		<pubDate>Wed, 16 Nov 2011 22:34:50 +0000</pubDate>
		<dc:creator>jpvincent</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[orienté objet]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://braincracking.org/?p=883</guid>
		<description><![CDATA[Après quelques années à écrire dans un langage, on finit facilement par oublier les premières difficultés que l&#8217;on avait rencontrées. Et à force de faire de la veille, de l&#8217;autoformation et de parler entre experts dans des conférences, j&#8217;ai un peu quitté la réalité de la majorité des équipes Web. Maintenant que je suis consultant [...]]]></description>
			<content:encoded><![CDATA[<p>Après quelques années à écrire dans un langage, on finit facilement par oublier les premières difficultés que l&rsquo;on avait rencontrées. Et à force de faire de la veille, de l&rsquo;autoformation et de parler entre experts dans des conférences, j&rsquo;ai un peu quitté la réalité de la majorité des équipes Web.</p>
<p>Maintenant que je suis consultant indépendant je retourne dans des équipes qui avaient autre chose à faire que de se demander si on a le droit de parler de classe en JavaScript, quelle est la bonne définition d&rsquo;une <em>closure</em>, ou quelles sont les fonctionnalités de EcmaScript 5 qui auraient du rester dans Ecmascript.Next.</p>
<p>J&rsquo;avais déjà parlé sur ce blog de <a href="http://braincracking.org/?p=89">JavaScript et la programmation orienté objet pour les développeurs PHP</a>, nous allons explorer ici les <strong>3 notions fondamentales de JavaScript</strong> qui sont probablement les plus grosses sources de bugs, d&rsquo;incompréhension et de frustration pour le développeur Web moyen. Et qui accessoirement sont la base d&rsquo;une programmation plus évoluée par la suite.</p>
<h1>JavaScript est différent : apprenez le</h1>
<p>Le monde du développement Web semble dominé par les langages dérivés de la syntaxe du C, PHP en tête, avec des paradigmes qui se ressemblent. Forcément en abordant JavaScript dont la syntaxe n&rsquo;est pas vraiment révolutionnaire, on est tenté d&rsquo;appliquer la même logique. Mais c&rsquo;est oublier un peu vite que ce langage a été créé il y a déjà 15 ans, quand Java était seulement à mode et pas encore ultra dominant comme aujourd&rsquo;hui, et qu&rsquo;il est principalement l&rsquo;héritier de langages comme Erlang et Lisp, aujourd&rsquo;hui très peu connus. En fait le mot Java dans JavaScript a été rajouté pour des raisons commerciales, et seuls quelques concepts comme la syntaxe et je crois la gestion des dates ont contribué à former JavaScript. JavaScript n&rsquo;est donc qu&rsquo;un cousin éloigné des langages <em>mainstream</em>.</p>
<p>Le maître mot de ses concepteurs semble avoir été la versatilité. Nous allons voir qu&rsquo;en explorant seulement 3 bases <em>à priori</em> simples, il est possible d&rsquo;obtenir à peu près n&rsquo;importe quoi, ce que les grands maître de JavaScript s&rsquo;amusent tous les jours à faire. En attendant de passer dans la catégorie des maîtres, il faut déjà maîtriser ces bases pour faciliter son travail au quotidien.</p>
<p>Nous allons donc nous baser sur EcmaScript 3 (le javascript de IE6-7-8) dont les trois fondamentaux sont :</p>
<ul>
<li>La portée des variables ( <code>var + function</code>)</li>
<li>Les fonctions</li>
<li>Le contexte (<code>this</code>)</li>
</ul>
<p>Commençons par la portée.<br />
<span id="more-883"></span></p>
<h1>La portée des variables</h1>
<h2>La théorie</h2>
<p>La portée, c&rsquo;est ce que voit l&rsquo;interpréteur à un moment donné de l&rsquo;exécution du code. Ouvrez un fichier JS, tapez le mot clé <code>debugger;</code> où bon vous semble, démarrez firebug ou votre outil préféré et cherchez l&rsquo;onglet &laquo;&nbsp;Espions&nbsp;&raquo; ou &laquo;&nbsp;Watch&nbsp;&raquo;.</p>
<div id="attachment_884" class="wp-caption aligncenter" style="width: 500px"><a href="http://94.23.51.58/jpvincent/blog/wp-content/uploads/2011/11/firebug-javascript-2.gif"><img class="size-full wp-image-884" title="Onglet Watch de Firebug" src="http://94.23.51.58/jpvincent/blog/wp-content/uploads/2011/11/firebug-javascript-2.gif" alt="" width="490" height="232" /></a><p class="wp-caption-text">L&#39;onglet Watch ou Espions de Firebug</p></div>
<p>La règle pour comprendre comment est créée une portée est très simple :</p>
<p style="text-align: center;">1 function = 1 portée</p>
<p>Concrètement vous avez la portée globale où tout se trouve (dans un navigateur, c&rsquo;est <code>window</code>), puis à chaque fonction que vous créez, vous créez une nouvelle portée, et celles ci peuvent s&rsquo;imbriquer à l&rsquo;infini. Chaque fois que vous précédez une assignation par le mot clé <code>var</code>, la variable n&rsquo;est visible qu&rsquo;à partir de cette portée.</p>
<pre><code>test1 = function() {
	var x = 1;
	test2 = function() {
		var x = 2;
		test3 = function() {
			var x = 3;
			console.log(x); // <strong>3</strong>
		}();
	}();
	console.log(x); // <strong>1</strong>
}();
console.log(x); // <strong>undefined</strong>
</code></pre>
<p>Si vous exécutez le code précédent dans votre console JavaScript, vous constaterez 3 choses :</p>
<ul>
<li>le <code>console.log</code> le plus profond affiche bien sur la dernière valeur de <code>x</code>, à savoir 3. Dans ce troisième niveau, on a écrasé les valeurs précédentes de <code>x</code>.</li>
<li>malgré cet écrasement à un niveau inférieur, le second <code>console.log</code> (qui affiche 1) montre bien que les nouvelles valeurs de <code>x</code> ne sont pas visibles depuis la première fonction.</li>
<li>enfin le dernier <code>console.log</code> est fait au niveau global, en dehors des définitions de fonction. Ici <code>x</code> n&rsquo;existe même pas.</li>
</ul>
<h2>La pratique</h2>
<p>Nous avons vu comment le couple <code>var</code> + <code>function</code> permet de définir une portée et empêche le code en dehors de la portée de voir certaines variables. Pourquoi ne pas tout mettre au niveau global ? Pour des raison d&rsquo;organisation du code et de maintenabilité ! Imaginez le code suivant :</p>
<pre><code>function genericFunctionName() {
	for(<strong>i</strong> = 0; i &lt; myArray.length; i++) {
		<strong>console.log(i);</strong>
	}
}
for(<strong>i</strong> = 0; i &lt; 10; i++) {
	genericFunctionName();
}
</code></pre>
<p>Nous avons simplement une fonction qui parcourt un tableau fictif, puis nous appelons cette fonction 10 fois. N&rsquo;exécutez surtout pas cela dans votre navigateur, car <strong>c&rsquo;est une boucle infinie</strong> !</p>
<p>En fait les deux boucles <strong>for</strong> utilisent le même nom de variable (<strong>i</strong>) pour compter les tours. C&rsquo;est un nom extrêmement commun et ça ne poserait pas de problème si les deux boucles ne pointaient pas sur <strong>la même variable</strong> ! Fixons cela.</p>
<pre><code>function genericFunctionName() {
	for( <strong>var i</strong> = 0; i &lt; myArray.length; i++) {
		console.log(i);
	}
}
for(i = 0; i &lt; 10; i++) {
	genericFunctionName();
}
</code></pre>
<p>Dans la fonction, nous avons rajouté le mot clé <code>var</code> pour spécifier que la variable n&rsquo;appartenait qu&rsquo;à cette fonction. Les deux bouclent ne pointent plus sur la même variable même si leurs noms sont les mêmes. C&rsquo;est très important pour le développeur de savoir qu&rsquo;il est le seul maître sur les variables qu&rsquo;il crée pour créer un code particulier. Ceci nous donne la première application concrète des portées.</p>
<h2>Créer son espace de travail sécurisé</h2>
<p>En tant que développeur, vous allez créer ou modifier du code sur des pages dont vous ne maîtrisez pas l&rsquo;environnement. Entre l&rsquo;historique du code, vos collègues et les publicités ou les widgets, beaucoup de variables sont créées ou écrasées au niveau global sans que vous ne puissiez le prévoir. Au milieu de cette tourmente, je vous propose de vous créer un petit havre de paix :</p>
<pre><code><strong>(function() { </strong>
<strong>}()) </strong>
</code></pre>
<p>Je vous conseille de démarrer tout fichier javascript ou tout code entre balise <code>&lt;script&gt;</code> par la première ligne et de toujours terminer par la dernière. Ce bout de code vous permet de poser les bases de votre portée et de créer des variables qui n&rsquo;appartiennent qu&rsquo;à vous, sans pour autant s&rsquo;isoler du reste du monde.</p>
<pre><code>(function() {
	var privateVariable = true;
	window.init = function() {
		console.log( privateVariable );
	}
}())
init(); // <strong>true</strong>
console.log(privateVariable); // <strong>undefined</strong> </code></pre>
<p>Exécutez ce code, et vous verrez que <code>privateVariable</code> n&rsquo;est pas accessible de l&rsquo;extérieur, mais que le code défini à l&rsquo;intérieur permet d&rsquo;y accéder. Très pratique en environnement hostile. Vous remarquerez aussi que l&rsquo;on rattache la fonction <code>init</code> directement à la portée globale, afin qu&rsquo;elle soit elle aussi visible de l&rsquo;extérieur.</p>
<h1>Les fonctions</h1>
<h2>C&rsquo;était si simple &#8230;</h2>
<p>Il est facile de créer une fonction et de l&rsquo;exécuter. Les syntaxes que vous utilisez au quotidien sont celles ci :</p>
<pre><code>// création v1
function action() {}
// création v2
action = function() {};
// exécution
action();
</code></pre>
<p>Simple non ?</p>
<h2>La fausse bonne idée</h2>
<p>Au fait quelle est la différence entre les deux manières de déclarer une fonction ? Pour la première ( <code>function nom()</code> ) le compilateur JavaScript extrait toutes les définitions et les met à disposition au niveau global AVANT de commencer l&rsquo;exécution. Concrètement vous pouvez même exécuter la fonction avant qu&rsquo;elle ne soit créée dans la source.</p>
<pre><code>// exécution avant la définition !
action();
// création
function action() {}
</code></pre>
<p>Cool ? Pas vraiment : c&rsquo;est systématiquement la dernière déclaration dans la source qui est prise en compte par les interpréteurs JS. Vous ne pouvez pas conditionner la définition des fonctions. Par exemple le code suivant ne va pas s&rsquo;exécuter comme vous pourriez le penser :</p>
<pre><code>
if( 1 == 1 ) {
	// l'exécution du code passe ici ...
	function action() {
		console.log('a == 1');
	}
} else {
	// ... pourtant le compilateur se souvient de cette fonction
	function action() {
		console.log('a != 1');
	}
}
action(); // <strong>a != 1 </strong>
</code></pre>
<p>Lors de l&rsquo;exécution, l&rsquo;interpréteur passe bien dans le premier <code>if</code> et pourtant c&rsquo;est la seconde définition qui est retenue, uniquement parce qu&rsquo;elle arrive en dernier dans la source.<br />
Et malgré cela, contrairement à d&rsquo;autres langages, la déclaration d&rsquo;une fonction n&rsquo;est valable que pour la portée en cours et ses descendantes. Dans le code suivant, la fonction <code>action</code> n&rsquo;est pas visible au niveau global :<br />
<code>
<pre>(function() {
	function action() {
		console.log('action');
	}
}())
action(); // undefined
</code></pre>
<p>La manière traditionnelle de déclarer les fonctions est donc assez trompeuse et de ce fait tombe doucement en désuétude. Pour des débutants on utilisera plutôt la seconde méthode qui a le mérite de pouvoir <strong>explicitement</strong> choisir la portée de ses fonctions, au même titre qu'une variable</p>
<pre><code>var action = function() {};</code></pre>
<p>En ce qui concerne le compilateur cette syntaxe est une variable avec pointeur sur une fonction anonyme. Le désavantage est que lorsque vous utilisez un débogueur pas à pas, la pile d'appels (<em>call stack</em>) ne vous affiche pas le nom des fonctions (l'anonymat sur Internet existe donc). Vous pouvez retrouver le nom de la variable assignée simplement en cliquant sur la fonction et en regardant dans la source.</p>
<h2>Particularités Javascript</h2>
<p>JavaScript a rajouté plusieurs particularités aux fonctions qui les rendent terriblement puissantes et flexibles. En fait toutes les constructions de code un peu élaborées telles que l'orientation objet ou l'application de <em>design pattern</em> se basent sur ces spécificités. Nous entrons donc dans le coeur de JavaScript.</p>
<h3>Auto-exécution</h3>
<p>En rajoutant simplement une paire de parenthèses après une déclaration, la fonction va immédiatement être exécutée.</p>
<pre><code>var autoInit = function() {
	console.log('hello world');
}<strong>()</strong>;
// <strong>hello world</strong>
</code></pre>
<p>Comme nous l'avons vu tout à l'heure, cela vous permettra principalement de créer des portées, pour protéger l'ensemble de votre script, et nous allons voir dans une minute que vous pouvez aussi l'utiliser dans certains cas particuliers.</p>
<h3>Classe ou fonction ?</h3>
<p>En JavaScript, tout est objet. Un objet n'est jamais qu'une collection de clés et de valeurs, et les valeurs peuvent être tout et n'importe quoi y compris d'autres objets. Lorsqu'une fonction est créée, automatiquement JavaScript y rajoute la propriété <code>prototype</code>. Tapez le code suivant dans votre console JavaScript :</p>
<pre><code>var myFunction = function() {};
console.log( myFunction.prototype ); // <strong>Object</strong>
</code></pre>
<p>Nous avons donc un objet <code>myFunction.prototype</code> et nous pouvons directement y accéder pour y rajouter des valeurs, comme d'autres fonctions par exemple. Ensuite pour accéder à ces fonctions, nous allons utiliser le mot clé <code>new</code>.</p>
<pre><code>// cette innocente fonction devient un constructeur
var myClass = function () {
	<strong>this.</strong>publicVariable = 0;
};
// accès au prototype
<strong>myClass.prototype</strong> = {
	decrement:function() {
		console.log( --this.publicVariable );
	},
	increment:function() {
		console.log( ++this.publicVariable );
	}
};

myObject = <strong>new myClass</strong>();
myObject.decrement(); // -1
myObject.decrement(); // -2

myObject2 = <strong>new myClass</strong>();
myObject2.increment(); // 1
myObject2.increment(); // 2
</code></pre>
<p>Entre nous, nous venons de créer quelque chose qui ressemble furieusement à une classe, avec une instanciation (<code>new myClass</code>), des variables propres à chaque instance ( <code>this.publicVariable</code> ) et un constructeur (le corps de la fonction).</p>
<h3>Orienté objet ?</h3>
<p>Si vous trouvez bizarre qu'une fonction se transforme soudainement en classe puis en objet, attendez de voir la suite. Toujours grâce à la notion du tout objet de JavaScript, nous pouvons également faire de l'héritage ! Là encore, en utilisant <code>.prototype</code>, nous allons créer une nouvelle fonction (ou classe) qui va hériter des méthodes de la première. Outre la déclaration de la nouvelle fonction, cela ne va prendre que deux lignes.</p>
<pre><code>mySubClass = function() {
	// maintenant on part de 10 au lieu de 0
	this.publicVariable = 10;
};
<strong>mySubClass.prototype = myClass.prototype;
mySubClass.prototype.constructor = mySubClass;</strong>

myObject2 = new mySubClass();
myObject2.increment(); // 11
myObject2.increment(); // 12
</code></pre>
<p>La première ligne après la déclaration de fonction fait pointer l'objet <code>.prototype</code> de notre nouvelle fonction vers l'objet <code>.prototype</code> de la classe mère, empruntant ainsi toutes ses propriétés. La seconde ligne est là pour rectifier un défaut de l'écrasement de <code>.prototype</code> : on refait pointer <code>.prototype.constructor</code> (encore une propriété automatiquement créée pour toutes les fonctions) vers le bon constructeur.</p>
<h3>Slip ou caleçon ?</h3>
<p>Pardon je voulais dire : pour les classes, vous êtes plutôt prototype ou closure ? On vient de voir que grâce à <code>.prototype</code> on pouvait émuler une classe en JavaScript. Les fonctions peuvent également renvoyer des objets simples contenant des propriétés et des méthodes, et la manière de les utiliser se rapprochera toujours terriblement d'une classe.</p>
<pre><code>myClass = function () { 
	// variable privée !
	var privateVariable = 0; 
	// méthodes publiques
	<strong>return { </strong>
		decrement:function() { 
			console.log( --privateVariable ); 
		}, 
		increment:function() { 
			console.log( ++privateVariable ); 
		} 
	<strong>}</strong> 
};
myObject = myClass(); 
myObject.decrement(); // -1 
myObject.decrement(); // -2 
myObject2 = myClass(); 
myObject2.increment(); // 1 
myObject2.increment(); // 2
</code></pre>
<p>Plusieurs différences par rapport à la version prototype :</p>
<ul>
<li>Notez le <code>return {...}</code> dans la définition de la fonction : vous pouvez y mettre exactement ce que vous auriez mis dans le prototype.</li>
<li>Vous pouvez utiliser la portée de la fonction constructeur pour avoir des variables privées (ici <code>var privateVariable</code>), alors qu'il n'est <strong>pas possible d'avoir des variables privées avec prototype</strong></li>
<li>Lorsque vous instanciez votre classe, vous n'avez plus besoin d'utiliser <code>new myClass()</code>, un simple appel sans <code>new</code> suffit.</li>
<li>Le mot clé <code>this</code> désigne l'objet renvoyé, alors qu'avec prototype il désignait le corps de la fonction constructeur. Généralement avec closure on n'utilise plus du tout <code>this</code></li>
<li>la création des fonction est évalué à chaque fois que vous invoquez la fonction constructeur, tandis que ce n'est fait qu'une seule fois avec prototype. <strong>N'utilisez jamais closure avec des objets qui peuvent être instanciés des centaines de fois</strong>.</li>
</ul>
<p>Voilà pour l'essentiel sur les fonctions : avec cela vous maîtrisez déjà leur portée et vous pouvez commencer à développer orienté objet, ce qui va vous permettre d'éviter beaucoup de bug et d'avoir un code plus maintenable.</p>
<h1>Le contexte ou this</h1>
<p><code>this</code> est le petit mot clé qui perd beaucoup de développeurs, notamment lorsque l'on est habitué aux dérivés du C comme PHP. En JavaScript comme ailleurs, il fait référence au contexte d'exécution, donc le code suivant s'exécutera probablement comme vous vous y attendez :</p>
<pre><code>myClass = function() { 
	this.id = <strong>'myClass'</strong>; 
} 
myClass.prototype = { 
	action:function() { 
		console.log( <strong>this.id</strong> ); 
	} 
}; 
myObject = new myClass(); 
myObject.action(); // <strong>'myclass'</strong>
</code></pre>
<p>Ici on a défini dans le constructeur <code>this.id</code> avec une certaine valeur, puis on instancie la classe (<code>new myClass()</code>) et la méthode <code>action()</code> accède tout naturellement à <code>this</code> pour retrouver la valeur de <code>id</code>.<br />
Pourtant lorsque vous voulez exécuter <code>myObject.action</code> au clic sur un élément du DOM, plus rien ne marche comme prévu.</p>
<pre><code>document.body.onclick = myObject.action; 
// document.body.id
 </code></pre>
<p><code> </code><br />
Vous pouvez exécuter les deux bouts de code précédent dans votre console JavaScript et cliquer sur la page, vous verrez que <code>this.id</code> n'est plus 'myClass' mais fait référence à l'<code>id</code> du <code>body</code>, qui n'existe peut être même pas. Ceci n'est pas particulier au DOM d'ailleurs, imaginez que vous créiez un autre objet qui aurait un événement <code>onfire</code> que vous auriez besoin d'écouter :</p>
<pre><code>myEvent = { 
	id:'myEvent' 
};
myEvent.onfire = myObject.action; 
myEvent.onfire(); // 'myEvent' au lieu de 'myClass'
</code></pre>
<p><code> </code><br />
Lorsque <code>onfire()</code> s'exécute, il exécute bien le corps de la fonction <code>action</code>, mais comme pour les objets du DOM, <strong><code>this</code> fait référence à l'objet d'où est exécutée la fonction</strong>, pas forcément à l'objet d'origine de la fonction.<br />
Ceci est du à la versatilité de JavaScript qui permet de très simplement copier le corps d'une fonction d'un objet à l'autre, alors que dans les langages traditionnels orienté objet il vous faut explicitement faire de l'héritage. Comment fixer cela ? Il y a au moins deux méthodes.</p>
<h2>Changement de contexte (natif)</h2>
<p>La première méthode est native à JavaScript et utilise la fonction <code>.call()</code>. Ici seule la dernière ligne a changé :</p>
<pre><code>myClass = function() { 
	this.id = 'myClass';
} 
myClass.prototype = { 
	action:function() { 
		console.log(this.id); 
	} 
}; 
myObject = new myClass(); 
myEvent = { 
	id:'myEvent' 
};
myEvent.onfire = myObject.action; 
<strong>myEvent.onfire.call( myObject ); // myClass</strong>
</code></pre>
<p><code> </code><br />
Le premier argument de la fonction <code>.call()</code> est l'objet qui sera utilisé pour <code>this</code>. Ici on redonne à <code>onfire</code> l'objet d'origine de la fonction <code>action</code>.<br />
Le problème avec cette solution, c'est qu'il faudrait que vous soyez certain que TOUS les endroits où votre fonction peut être appelée vont rectifier le contexte d'exécution. Hors ne serait ce que pour les événement natifs du DOM cela n'est pas possible, sauf si vous utilisez une bibliothèque de manière systématique. Donc faire confiance à <code>this</code> n'est raisonnable que si vous maîtrisez parfaitement tout le code qui sera écrit.</p>
<h2>Conservation du contexte (à la main)</h2>
<p>Pour éviter ces problèmes de maintenance, la solution en vogue est de tout simplement ne jamais utiliser <code>this</code> directement et de préférer utiliser la syntaxe closure et une variable privée pour définir ses classes.</p>
<pre><code>myClass = function() { 
	this.id = 'myClass';
	// capture du contexte
	<strong>var me = this;</strong>
	return {
		action:function() {
			console.log( <strong>me.id</strong> );
		}
	}
};
myObject = myClass(); 
document.body.onclick = myObject.action; 
// 'myClass'
</code></pre>
<p><code> </code><br />
On voit donc ici :</p>
<ul>
<li>dans le constructeur, on capture le contexte avec une variable privée : <code>var me = this</code></li>
<li>dans la fonction <code>action</code> on n'utilise plus <code>this</code> mais <code>me</code></li>
</ul>
<p>Peu importe l'endroit d'où est lancé la fonction (ici au clic sur la page), et peu importe la valeur réelle de <code>this</code>, on est maintenant certain que l'on aura toujours un accès à l'objet originel grâce à une variable privée. Bien sur <code>this</code> reste utilisable normalement, notamment si vous avez besoin de retrouver l'objet DOM cliqué par exemple.</p>
<p>Pour encore plus de souplesse avec les fonctions de JavaScript, allez voir <a href="http://braincracking.org/?p=896">la deuxième partie de cet article</a>.</p>
<h1>L'essentiel</h1>
<p>Si vous ne deviez retenir que quelques points, les voici :</p>
<ul>
<li>JavaScript a des concepts différents des langages majeurs et devient extrêmement important sur votre CV. Prenez le temps de l'apprendre</li>
<li>Les bibliothèques telles que jQuery ne sont pas faites pour couvrir les cas que nous venons de voir. jQuery permet d'utiliser le DOM sereinement, pas d'organiser votre code proprement.</li>
<li>Lorsque vous créez une classe, choisissez la syntaxe prototype pour la performance ou closure pour les variables privées et la maîtrise du contexte d'exécution</li>
<li>N'utilisez plus la syntaxe <code>function maFonction() {}</code></li>
<li>Utilisez systématiquement la fonction anonyme auto-exécutée ( <code>(function() { var .. }())</code>) en début et fin de fichier ou de <code>&lt;script&gt;</code></li>
<li>Utilisez systématiquement <code>var</code> pour vos variables, y compris celles qui font référence à des fonctions</li>
</ul>
<p>Dernière chose : j'ai essayé d'être pratique, mais lire un post de blog ne suffit jamais pour comprendre des concepts de programmation : codez !</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/braincracking?a=LaZUIJNHUM0:rSU7mUrR05I:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/braincracking?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=LaZUIJNHUM0:rSU7mUrR05I:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/braincracking?i=LaZUIJNHUM0:rSU7mUrR05I:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=LaZUIJNHUM0:rSU7mUrR05I:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/braincracking?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=LaZUIJNHUM0:rSU7mUrR05I:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/braincracking?i=LaZUIJNHUM0:rSU7mUrR05I:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=LaZUIJNHUM0:rSU7mUrR05I:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/braincracking?i=LaZUIJNHUM0:rSU7mUrR05I:V_sGLiPBpWU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/braincracking/~4/LaZUIJNHUM0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://braincracking.org/2011/11/16/javascript-3-fondamentaux/feed/</wfw:commentRss>
		<slash:comments>27</slash:comments>
		<feedburner:origLink>http://braincracking.org/2011/11/16/javascript-3-fondamentaux/</feedburner:origLink></item>
		<item>
		<title>HTML5 maintenant, chapitrage de la conférence</title>
		<link>http://feedproxy.google.com/~r/braincracking/~3/J2fZKVqSyZw/</link>
		<comments>http://braincracking.org/2011/03/01/html5-maintenant-chapitrage-de-la-conference/#comments</comments>
		<pubDate>Tue, 01 Mar 2011 12:00:44 +0000</pubDate>
		<dc:creator>jpvincent</dc:creator>
				<category><![CDATA[HTML5]]></category>
		<category><![CDATA[conférence]]></category>

		<guid isPermaLink="false">http://braincracking.org/?p=866</guid>
		<description><![CDATA[La vidéo sur la conférence que j‘ai donné à Paris Web 2010 vient de sortir, aussi comme pour la conférence sur les Performances Web je l‘ai chapitré et je vous remets les slides pour que vous vous y retrouviez. Mes capacités d‘orateur valent ce qu‘elles valent, mais le contenu et le discours restent d‘actualité et [...]]]></description>
			<content:encoded><![CDATA[<p>La vidéo sur la conférence que j‘ai donné à Paris Web 2010 vient de sortir, aussi comme pour la conférence sur <a href="http://braincracking.org/?p=790">les Performances Web</a> je l‘ai chapitré et je vous remets les slides pour que vous vous y retrouviez.</p>
<p>Mes capacités d‘orateur valent ce qu‘elles valent, mais le contenu et le discours restent d‘actualité et devraient permettre je l‘espère à certains développeurs de se décoincer face à HTML5 : les fonctionnalités sont utilisables maintenant en production, pour peu qu‘on sache coder, utiliser des librairies faites pour ça et qu‘on soit suffisamment curieux pour tester tout cela. Les bénéfices sont soit immédiats soit à venir, et il y a certains écueils à connaître.<br />
Le maître mot est : testez ! Dans la plupart des cas vous vous rendrez compte que vous pouvez mettre en production et donc améliorer votre site pour vos utilisateurs.<br />
<span id="more-866"></span></p>
<h2>Le chapitrage</h2>
<p>La conférence :</p>
<ul id="playlist">
<li><a data-start="5">0:05</a> : bonjour</li>
<li><a data-start="70">1:10</a> : relativisier l&rsquo;état des specs</li>
<li>l‘exemple de Web Storage
<ul>
<li><a data-start="180">3:00</a> : 7 implémentations, mais utilisable</li>
<li><a data-start="270">4:30</a> : librairies d‘accès à Web Storage</li>
<li><a data-start="340">5:40</a> : Exemples d&rsquo;utilisation de Web Storage</li>
</ul>
</li>
<li><a data-start="385">6:25</a> : HTML5, c&rsquo;est gros, et alors ?</li>
<li>La nouvelle sémantique
<ul>
<li><a data-start="430">8:30</a> : le doctype</li>
<li><a data-start="830">9:20</a> : nouvelles balises (<code>nav, article, header</code>, légendes &#8230;</li>
<li><a data-start="810">13:30</a> : microdata</li>
<li><a data-start="975">16:15</a> : nouveaux types de champs de formulaire</li>
</ul>
</li>
<li><a data-start="1135">18:55</a> : les APIs JS
<ul>
<li><a data-start="1165">19:25</a> : est on vraiment dans la nouveauté ? Listing des fonctionnalités qui ont déjà un équivalent</li>
<li><a data-start="1317">21:57</a> : comportement des formulaires, <a href="http://www.alistapart.com/d/forward-thinking-form-validation/enhanced_2.html">démo</a> de librairies sous IE6</li>
<li><a data-start="1440">24:00</a> : intérêt d&rsquo;utiliser quand même le standard HTML5 pour les formulaires</li>
</ul>
</li>
<li><a data-start="1625">27:05</a> : Géolocalisation navigateur : <a href="http://jsfiddle.net/braincracking/EbeJQ/">démo</a> et intérêt par rapport à la géolocalisation par IP, alternative</li>
<li><a data-start="1920">32:00</a> : SVG : Démo sur IE6 grâce à la <a href="http://raphaeljs.com/analytics.html">librairie raphaelJS</a></li>
<li><a data-start="2060">34:20</a> : La vidéo HTML5 : limites et <a href="http://praegnanz.de/html5video/">librairies</a></li>
<li><a data-start="2190">36:30</a> : Drag and Drop et sélection multiple : démo IE6 (applet, flash), retour d&rsquo;implémentation en prod, transcodage en HTML5</li>
<li><a data-start="2460">41:10</a> : conclusion : partez sur <a href="http://braincracking.org/?p=764">les standards</a>, utilisez <a href="https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-browser-Polyfills">les librairies</a>, jouez et testez</li>
</ul>
<p>Vu mon débit de parole lorsque je suis sous le feu de la rampe j‘ai terminé 10 minutes avant l‘heure prévue. La scéance de question / réponses a donc pu être longue et très intéressante :</p>
<ul>
<li>44:10 : la remarque qui tue à propos de l‘accessibilité actuelle de HTML5 par Aurélien Levy (j&rsquo;ai développé ses argument dans ce post sur <a href="http://braincracking.org/?p=860">l&rsquo;accessibilité  de HTML5</a>). Pour résumer : je maintiens que à part 2 bugs, l‘accessibilité n‘est pas dégradée même pour IE6.</li>
<li>47:30 : remarque sur la surenchère de librairie JS sur les formulaires chez certaines sociétés</li>
<li>49:20 : on revient sur ma mauvaise opinion de l‘implémentation de la vidéo HTML5</li>
<li>51:20 : ARIA sera t il toujours utile ? (oui) </li>
<li>52:00 : on re-discute de l‘accessibilité de HTML5 entre pros</li>
<li>53:45 : HTML5 boilerplate</li>
<li>54:05 : question sur l‘interprétation du doctype HTML5 par IE6 (réponse mal dite : IE n‘a que 2 modes, standard ou quirskmode)</li>
<li>55:25 : inquiétude sur les failles de sécurité des librairies</li>
</ul>
<h2>La vidéo</h2>
<div id="container-player-html5-now">
    <a href="http://www.dailymotion.com/video/xh9c18">Vous trouverez la vidéo en ligne sur dailymotion</a>
</div>
<p><script>
var	sPlayerId = 'player-html5-now',
	sDailymotionID = 'xh9c18',
	oPlayer,
	playList = document.getElementById('playlist').getElementsByTagName('A');
BC.loadJS('http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js', function() {
	var	params = { allowScriptAccess: "always" },
		atts = { id: sPlayerId };
	swfobject.embedSWF('http://www.dailymotion.com/swf/'+sDailymotionID+'?enableApi=1&#038;playerapiid='+sPlayerId,
                       'container-'+sPlayerId, "600", "400", "9", null, null, params, atts);
});
var onTimeClick = function() {
	oPlayer.seekTo( this.getAttribute('data-start') );
};
function onDailymotionPlayerReady() {
	oPlayer = document.getElementById(sPlayerId);
	for(var i=0; i < playList.length; i++) {
		playList[i].onclick = onTimeClick;
	}
};
</script></p>
<h2>Les slides</h2>
<p>Les slides vus à la conférence sont ceux ci :<br />
<a title="HTML5 c'est maintenant" href="http://www.slideshare.net/jpvincent/html5-now-light">HML5 c‘est maintenant (IE6 inclus)</a><br />
<iframe style="border:none;width:520px;height:420px;" src="http://braincracking.org/slidesharehtml/embed.php?width=500&#038;url=http://www.slideshare.net/jpvincent/html5-now-light"></iframe></p>
<p>Vous trouvez 3 fois plus de détails concernant HTML5 dans <a href="http://braincracking.org/?p=597">une autre série de slides</a>, avec notamment le détail de Audio/Video, un exemple de microdata, le détail du problème des nouveaux éléments et du localStorage et une implémentation de géolocalisation. Bref, à regarder au calme chez soi pour se former.</p>
<h2>Une suite ?</h2>
<p>Ma prochaine conf sur HTML5 sera plus petite, mais complémentaire de celle ci : à la <a href="http://www.kiwiparty.fr/">Kiwi Party</a> organisée par Alsacréations, j‘essaierais de montrer qu‘intégrer HTML5 dans son processus de fabrication de site ne devrait rien changer tant qu'on respecte déjà les bonnes pratiques.<br />
En parallèle mon projet actuel tourne uniquement autour du passage à HTML5, j‘aurais l‘occasion de vous en reparler dès qu‘il pourra être rendu public.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/braincracking?a=J2fZKVqSyZw:YquXH-6iR_Q:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/braincracking?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=J2fZKVqSyZw:YquXH-6iR_Q:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/braincracking?i=J2fZKVqSyZw:YquXH-6iR_Q:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=J2fZKVqSyZw:YquXH-6iR_Q:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/braincracking?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=J2fZKVqSyZw:YquXH-6iR_Q:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/braincracking?i=J2fZKVqSyZw:YquXH-6iR_Q:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=J2fZKVqSyZw:YquXH-6iR_Q:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/braincracking?i=J2fZKVqSyZw:YquXH-6iR_Q:V_sGLiPBpWU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/braincracking/~4/J2fZKVqSyZw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://braincracking.org/2011/03/01/html5-maintenant-chapitrage-de-la-conference/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://braincracking.org/2011/03/01/html5-maintenant-chapitrage-de-la-conference/</feedburner:origLink></item>
		<item>
		<title>Etat des lieux de l‘accessibilité de HTML5</title>
		<link>http://feedproxy.google.com/~r/braincracking/~3/nE8rUeofJlE/</link>
		<comments>http://braincracking.org/2011/02/19/etat-des-lieux-de-laccessibilite-de-html5/#comments</comments>
		<pubDate>Sat, 19 Feb 2011 09:39:07 +0000</pubDate>
		<dc:creator>jpvincent</dc:creator>
				<category><![CDATA[HTML5]]></category>
		<category><![CDATA[Accessibilité]]></category>
		<category><![CDATA[sémantique]]></category>

		<guid isPermaLink="false">http://braincracking.org/?p=860</guid>
		<description><![CDATA[Après avoir affirmé à Paris Web 2010 que HTML5 était utilisable immédiatement en production, un expert accessibilité m‘a repris en disant qu‘il était dangereux de dire que HTML5 était accessible (j‘en parlais au futur cela dit). Dans le cadre d‘un gros projet autour de HTML5, j‘ai depuis fait pas mal de recherches ce qui m‘a [...]]]></description>
			<content:encoded><![CDATA[<p>Après avoir affirmé à Paris Web 2010 que <a href="http://braincracking.org/?p=597">HTML5 était utilisable immédiatement en production</a>, un expert accessibilité m‘a repris en disant qu‘il était dangereux de dire que HTML5 était accessible (j‘en parlais au futur cela dit). Dans le cadre d‘un gros projet autour de HTML5, j‘ai depuis fait pas mal de recherches ce qui m‘a permis de mieux comprendre son intervention.<br />
Je sais qu‘il est dangereux de parler en dehors de son domaine d‘expertise, mais il faut bien qu‘un développeur Web mette les pieds dans le plat et à tout le moins provoque le débat. Autant vous dire que si vous vous y connaissez en accessibilité, je prend tout ajout ou correction.</p>
<p>Autant vous le dire tout de suite, mes conclusions sont mitigées, et il se peut même que je revienne sur ce que j‘affirmais à l‘époque.<br />
<span id="more-860"></span></p>
<h2>Quel HTML5 ?</h2>
<p>Le terme commençant à être flou, il vaut mieux le préciser à chaque fois qu&rsquo;on l&rsquo;évoque : pour une fois sur ce blog le HTML5 dont nous parlerons dans cet article représente uniquement <a href="http://www.w3.org/TR/html5/content-models.html#annotations-for-assistive-technology-products-aria">la spécification adoubée par le W3C</a>, celle qui représente l‘évolution de HTML4 avec les nouvelles balises, le nouvel algorithme de parsing, canvas et le multimédia.</p>
<h2>Les nouvelles balises</h2>
<h3>Leur apport</h3>
<p>Les balises comme <code>article</code>, <code>time</code>, <code>header</code>, <code>nav</code> ou <code>figure</code> apportent de la sémantique à votre page. Cela signifie concrètement plusieurs choses :</p>
<ul>
<li>une meilleure <strong>lisibilité du code</strong>, ce qui est important pour ceux qui l&rsquo;écrivent et facilite la maintenance</li>
<li>une (future) exploitation facilitée pour les tiers :  <a href="https://www.readability.com/">Readability</a> (Application de lecture, service de rétribution des auteurs de blogs) se base sur ces nouvelles balises (ou sur microformat) pour tirer les informations des articles des pages. Il est difficile de trouver d‘autres exemples pour le moment.</li>
<li>un (futur) meilleur référencement : la position officielle de Google sur le sujet est qu‘ils adaptent leurs algos à toutes les pratiques émergentes. Si beaucoup de sites utilisent <code>article</code>, google finira par l‘interpréter.</li>
<li>une (future) meilleure accessibilité : les navigateurs vont <a href="http://www.w3.org/TR/html5/content-models.html#annotations-for-assistive-technology-products-aria">rajouter automatiquement</a> des rôles ARIA sur certaines balises. <a href="http://www.html5accessibility.com/">Ce tableau</a> vous montre le support actuel, il est aujourd‘hui très limité : Firefox 4 pour certaines balises, Opéra pour les formulaires sont leaders</li>
</ul>
<p>Bref, les apports immédiats pour tous les sites ne sont pas évidents. Il y aura tout de même un bonus pour ceux qui jouent l‘innovation et y passent avant les concurrents lorsque ces lecteurs de code source (services, moteurs de recherche, navigateurs) exploiteront cette mine d&rsquo;informations.</p>
<h3>Les problèmes</h3>
<p>Le reproche principal fait aux nouvelles balises, c‘est que <abbr title="Internet Explorer versions 6 à 8">IE6-8</abbr> font disparaître du DOM les éléments qu‘il ne connaît pas, et donc ne les présentent pas aux technologies d‘assistance. Le moyen de contourner cela <a title="lien vers le projet HTML5 shim" href="http://code.google.com/p/html5shim/">est connu</a>, facile à mettre en place et <em>bullet-proof</em> mais il induit une <strong>dépendance envers JavaScript</strong>. Les derniers <a href="http://developer.yahoo.com/blogs/ydn/posts/2010/10/how-many-users-have-javascript-disabled/">chiffres français</a> pris sur la homepage de Yahoo! font état de 1.5% d‘utilisateurs dans cet état. La part de marché de IE est d‘environ 50%, cela vous laisse avec 0.7% d‘utilisateurs que cela peut gêner parmi vos visiteurs handicapés.</p>
<p>A ma connaissance, il y a 2 autres choses qui ont donné une mauvaise réputation à ces nouveaux éléments :</p>
<ul>
<li>une combinaison de certaines versions de <abbr title="Leader des lecteur d‘écran">JAWS</abbr> et de Firefox avait un bug qui faisait <strong>disparaître le contenu</strong> situé dans une balise <code>&lt;header&gt;</code>. En plus de la perte brute de contenu, selon où elle est placée, <code>&lt;header&gt;</code> peut contenir des titres ou des liens, 2 éléments fondamentaux pour la navigation avec les technologies d‘assistance.</li>
<li>Une autre combinaison, celle de versions de <abbr title="Second sur le marché des lecteurs d‘écran">Windows-Eyes</abbr> et d‘Internet Explorer, n‘arrivait pas à lister les liens à l‘intérieur d‘éléments HTML5 avec une balise <code>role</code>. C‘est très spécifique mais là aussi il y a perte d‘éléments de navigation fondamentaux.</li>
</ul>
<p>Doit on changer sa manière de coder parce 2 logiciels buguent ? Historiquement les développeurs Web ont toujours répondu oui à cette question, en changeant leur code pour s‘adapter aux bugs de IE par exemple. Sauf que IE est officiellement supporté par tous les sites Web alors que ce n‘est pas le cas pour ces 2 logiciels. Même si ces bugs ont été corrigés, <strong>ils restent majeurs</strong> (perte de contenu). Je n‘ai pas de chiffre sur le taux de pénétration de ces versions buguées, mais les <a href="http://webaim.org/projects/screenreadersurvey/">seuls chiffres publics</a> que j&rsquo;ai pu trouver montrent que 25% de ces utilisateurs n‘ont pas mis à jour leur version après un an, ce qui signifie qu‘il faut prendre en compte ces bugs plusieurs années.</p>
<p><strong>En conclusion</strong> : l‘introduction des nouvelles balises est surtout compromise par des bugs majeurs de certains logiciels importants et votre <strong>sentiment</strong> sur la dépendance à JavaScript (que vous devriez d‘ailleurs mesurer sur votre site). Elle est à mettre en balance avec les avantages de ces balises, qui eux ne sont pas immédiats.</p>
<h2>Les zones de navigation</h2>
<p>L‘introduction des balises <code>nav</code>, <code>header</code>, <code>footer</code> et <code>aside</code> est très intéressante car elle permet au navigateur de fournir aux technologies d‘assistance une carte de la page. Jusqu‘ici les utilisateurs de ces technologies naviguaient principalement avec la liste des titres et la liste des liens d‘une page, ils pourraient également avoir accès automatiquement aux zones classiques présentes sur les sites Web.</p>
<p>Première ombre au tableau, HTML5 <a href="http://www.w3.org/TR/html5/content-models.html#annotations-for-assistive-technology-products-aria">définit</a> un mapping strict entre certaines balises et des rôles de zone ARIA, mais sur ces zones là il n‘y a pas de rôle par défaut. Il y a donc contradiction entre la spécification et les rôles que les navigateurs devraient automatiquement implémenter ( <code>&lt;nav role="navigation"&gt;</code>, <code>&lt;header role="banner"&gt;</code>, <code>&lt;footer role="contentinfo"&gt;</code>, <code>&lt;aside role="complementary"&gt;</code>). Qui dit contradiction dit mésentente possible entre navigateurs.</p>
<p>Ensuite vient le support : la traduction automatique des balises en rôle de zone ARIA par les navigateurs arrive à peine, Firefox 4 étant pour le moment seul. Par contre ARIA est bien supporté par les versions récentes des lecteurs d‘écran. Sauf que comme pour les navigateurs, les clients de ces logiciels mettent un certain temps avant de passer aux nouvelles versions.</p>
<p>Enfin, ces rôles et ces balises sont censées permettre la disparition des liens d‘échappement, bonne pratique d‘accessibilité reconnue. Mais ça serait oublier ceux qui n‘utilisent pas ces logiciels, mais qui naviguent tout de même au clavier (choix, accident de souris, mauvais matériel, certains mobiles &#8230;). A ma connaissance les navigateurs n‘ont pas prévu de fonctionnalité pour ces utilisateurs en leur mettant à disposition des raccourcis vers ces zones.</p>
<p><strong>En conclusion</strong> : la technique du lien d‘évitement restera très longtemps un moyen de navigation plus universel. Si vous ne la pratiquiez pas, utiliser les nouvelles balises maintenant apportera naturellement de l‘accessibilité au fur et à mesure du déploiement des nouvelles versions de navigateurs et de technologie d‘assistance</p>
<h2>Le multimédia</h2>
<p>Les éléments <code>audio</code> et <code>video</code> natifs ont fait rêver un peu tout le monde, et sur le papier règlent d‘épineux problèmes. En pratique c‘est beaucoup plus compliqué (sur mon projet, nous avons jugé que les implémentations navigateur ne valaient pas encore Flash) et l‘accessibilité n‘est pas en reste. Les implémentations des navigateurs concernant la navigation clavier sont variées, parfois buguées et parfois inexistantes.</p>
<p>Les sous-titres ne sont implémentés nativement nul part et les spécifications ont vraiment beaucoup bougé à ce sujet. Difficile de savoir si le consensus actuel autour de l‘élément <code>track</code> et le format WebSrt va rester.</p>
<p>Comme vous devez de toute manière fournir une lecture de la vidéo en Flash, qui lui est naturellement encore moins accessible (il pourrait, mais les flasheurs ne le font pas), votre seule option est de coder vous même un lecteur vidéo accessible, en sortant les contrôles du lecteur (natif ou Flash) pour en faire des éléments HTML marqués avec <a href="http://dev.opera.com/articles/view/more-accessible-html5-video-player/#wai-aria">ARIA</a>, et d‘implémenter votre propre solution de sous-titrage en Javascript. Mais vous sacrifiez l‘option fullscreen, ce qui est rarement toléré.</p>
<p><strong>Conclusion</strong> : les balises <code>video</code> et <code>audio</code> sont vraiment trop jeunes concernant l‘accessibilité, et il n‘y a pas de gros bénéfice à en tirer sur les navigateurs de bureau. Flash étant pire, vous devez améliorer vous même les choses en codant un player accessible ou en espérant en trouver un dans <a href="http://praegnanz.de/html5video/">cette longue liste</a>.</p>
<h2>Les titres</h2>
<p>HTML5 <a href="http://www.w3.org/TR/html5/sections.html#outlines">définit un algorithme</a> pour déterminer le vrai niveau des <code>Hx</code> d‘une page. Concrètement si vous mettez un <code>h1</code> dans une balise <code>section</code> ou <code>article</code> qui n‘est elle même pas enfant d‘une autre balise sectionnante, alors votre <code>h1</code> est en fait un <code>h2</code>. C‘est très pratique pour ceux qui développent des sites Web de façon modulaire : on ne s‘occupe que de la hiérarchie interne d‘un bout de page, sans avoir à se demander quel est le nombre de niveaux de titre déjà introduit. Pour voir cet algorithme en action, vous pouvez utiliser l‘outil <a href="http://code.google.com/p/h5o/">HTML5 outliner</a>.</p>
<p>En quoi est ce important ? les titres sont la première manière de naviguer sur une page lorsque l‘on utilise un lecteur d‘écran et selon le moteur HTML utilisé, la hiérarchie interprétée ne sera pas la même, et vous ne pouvez rien y faire. Honnêtement si vous n&rsquo;aviez pas prêté attention à la hiérarchie globale des titres jusqu‘à présent, HTML5 vous aidera au contraire à mieux vous organiser module par module et obtenir au final quelque chose de cohérent au moins sur les nouveaux navigateurs. Si vous aviez une belle hiérarchie, alors pour la conserver sur tous les navigateurs, il vous faudra éviter les balises sectionnantes comme <code>article</code>, <code>section</code> ou <code>aside</code>.</p>
<p>Cela dit, une hiérarchie bien maîtrisée de titres n‘est réellement importante que si la page comporte beaucoup de titres, par exemple sur des sites à fort contenu textuel (longs articles de journaux, encyclopédie &#8230;). La plupart des sites se contentent d‘une vingtaine de titres de niveau 1 et 2.</p>
<p>Conclusion : Si vous ne gériez pas votre hiérarchie parfaitement au niveau de la page (site très modulaire, maintenu par plusieurs personnes ou par méconnaissance), autant passer directement à la logique HTML5, vous devrez vivre avec une hiérarchie de titres différente selon le navigateur. Si vous aviez une belle hiérarchie et beaucoup de titres, alors pour la conserver sur tous les navigateurs, il vous faudra éviter les balises sectionnantes comme <code>article</code>, <code>section</code> ou <code>aside</code>.</p>
<h2>Canvas</h2>
<p>Canvas est effectivement un trou noir d‘où rien ne sort, et ironiquement même Flash peut être plus accessible que cette balise (encore une fois, si le développeur Flash a fourni un effort supplémentaire). Seul IE9 permet d‘accéder au <em>shadow DOM</em>, mais en supposant que tous les navigateurs fassent de même, la question de l‘intérêt se pose : pourquoi accéder à des paquets de pixels ? Si vous l‘utilisez pour obtenir des effets graphiques décoratifs, un contenu alternatif textuel peut suffire. Si vous l‘utilisez pour la navigation, vous vous êtes probablement trompé de technologie. Si votre application repose de manière justifiée sur cette technologie, comme pour un jeu, alors il me semble de toute façon impossible de rendre accessible ce type d‘application très graphique.</p>
<p>Conclusion : ressortez donc les bonnes pratiques, fournissez un contenu alternatif si c‘est possible et évaluez bien vos besoins : SVG / VML ou une navigation scriptée peuvent suffire.</p>
<h2>Passer à ARIA</h2>
<p>Ma conclusion personnelle est qu‘il faut rajouter ARIA et ses multiples rôles à votre page HTML5. Voici ce que j‘utilise occasionnellement pour tester l‘ajout d‘ARIA ou pour vérifier l‘accessibilité d‘une page. Pour tester ARIA, il vous faut un Windows, un Firefox et un Internet Explorer 8 qui sont les 2 navigateurs les plus utilisés par les clients des lecteurs d‘écran. Ce sont également les 2 navigateurs qui supportent le mieux ARIA. En lecteur d‘écran <a href="http://www.freedomscientific.com/fs_products/software_jaws.asp">JAWS</a> par Freedom Scientific est clairement le leader du marché, suivi par <a href="http://www.gwmicro.com/Window-Eyes/">Window-Eyes</a> de GW Micro. Ils offrent tous deux des version d‘essai gratuit dont la limite est que vous devez redémarrer Windows toutes les 40 minutes. Astuce : utilisez des machines virtuelles, et la fonctionnalité <em>snapshot</em> pour vous éviter ces redémarrages fastidieux. Vous pouvez également utiliser un lecteur d‘écran open-source : <a href="http://www.nvda-project.org/">NVDA</a> ainsi que la toolbar <a href="https://addons.mozilla.org/fr/firefox/addon/juicy-studio-accessibility-too/">Juicy Studio Accessibility Toolbar</a> pour Firefox qui permet de vérifier ses zones pendant le développement.</p>
<h2>Conclusion</h2>
<p>Vaste sujet que l‘accessibilité de HTML5, et j‘imagine (j‘espère!) que des experts accessibilité passeront sur ce blog pour me corriger ou rajouter d‘autres difficultés. En conclusion :</p>
<ul>
<li>il me faut l‘admettre, l‘introduction des nouvelles balises peut causer des bugs majeurs ou gêner des logiciels de lecture d‘écran. Ces bugs et cette gêne de la hiérarchie sont là pour plusieurs années tandis que les avantages des nouvelles balises ne sont pas encore massivement arrivés. A vous de voir
<li>l‘utilisation des balises <code>video</code> et <code>audio</code> est prématurée à tous les points de vue
<li>il va falloir encore du temps avant que HTML5 vous apporte plus d‘accessibilité que ARIA. Soit vous passez à ARIA immédiatement, soit vous pariez sur le futur
</ul>
<p>Si le ton négatif de ce billet vous fait conclure qu‘il ne faut pas utiliser HTML5, alors je vous invite à me relire : j&rsquo;ai principalement <strong>listés les problèmes</strong> afin que vous sachiez à quoi vous vous engagez en restant sur les techniques actuelles ou en partant sur certaines nouveautés de HTML5. HTML5 au sens des applications Web avec toutes ses nouvelles APIs JS ne sont ici pas concernées.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/braincracking?a=nE8rUeofJlE:XbJs_Z0cbPI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/braincracking?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=nE8rUeofJlE:XbJs_Z0cbPI:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/braincracking?i=nE8rUeofJlE:XbJs_Z0cbPI:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=nE8rUeofJlE:XbJs_Z0cbPI:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/braincracking?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=nE8rUeofJlE:XbJs_Z0cbPI:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/braincracking?i=nE8rUeofJlE:XbJs_Z0cbPI:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=nE8rUeofJlE:XbJs_Z0cbPI:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/braincracking?i=nE8rUeofJlE:XbJs_Z0cbPI:V_sGLiPBpWU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/braincracking/~4/nE8rUeofJlE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://braincracking.org/2011/02/19/etat-des-lieux-de-laccessibilite-de-html5/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		<feedburner:origLink>http://braincracking.org/2011/02/19/etat-des-lieux-de-laccessibilite-de-html5/</feedburner:origLink></item>
		<item>
		<title>Conférence performance à Paris Web 2010</title>
		<link>http://feedproxy.google.com/~r/braincracking/~3/IK55nE_4wac/</link>
		<comments>http://braincracking.org/2011/02/03/conference-performance-a-paris-web-2010/#comments</comments>
		<pubDate>Thu, 03 Feb 2011 12:51:55 +0000</pubDate>
		<dc:creator>jpvincent</dc:creator>
				<category><![CDATA[Performances]]></category>
		<category><![CDATA[conférence]]></category>
		<category><![CDATA[Perfs]]></category>

		<guid isPermaLink="false">http://braincracking.org/?p=790</guid>
		<description><![CDATA[J&#8217;avais un atelier sur les performances pour le cycle de conférence Paris Web 2010, qui est maintenant sorti en vidéo. L&#8217;atelier s&#8217;est finalement transformé en une conférence improvisée d&#8217;1h30, par manque de candidats pour tester leurs sites, et de par la configuration de la pièce (amphi au lieu de salle de cours). Malheureusement le côté [...]]]></description>
			<content:encoded><![CDATA[<p>J&rsquo;avais un <a href="http://www.paris-web.fr/2010/programme/performance-web.php">atelier sur les performances</a> pour le cycle de conférence Paris Web 2010, qui est maintenant sorti en vidéo. L&rsquo;atelier s&rsquo;est finalement transformé en une conférence improvisée d&rsquo;1h30, par manque de candidats pour tester leurs sites, et de par la configuration de la pièce (amphi au lieu de salle de cours). Malheureusement le côté improvisé se ressent un peu car je ne m&rsquo;étais pas chronométré pour réussir à synthétiser chaque sujet.<br />
Chaque sujet est donc discuté en profondeur, mais je n&rsquo;ai pu traiter que les bases. Voici le chapitrage de cette conférence :<br />
<span id="more-790"></span></p>
<ul id="playlist">
<li><a data-start="0">0 à 10:30</a> : relation chiffre d&rsquo;affaire et temps d&rsquo;affichage
<li><a data-start="630">10:30</a> : référencement et webperf
<li><a data-start="750">12:30</a> : quelles sont les mesures à prendre en compte ?</li>
<ul>
<li>comparaison affichage 01net / evene.fr
<li>utilisation webpagetest.org
	</ul>
<li><a data-start="1280">21:20</a> : contre-performance du protocole HTTP, parallélisation et latence
<li><a data-start="1460">24:20</a> les JS/CSS (outil cuzillion), quels navigateurs tester ?
<li><a data-start="2038">33:58</a> : outils pour JS/CSS
<li><a data-start="2500">41:40</a> : organisation du code JS (bottom, loader)
<li><a data-start="2890">48:10</a> : minifier le HTML ?
<li><a data-start="2999">49:59</a> : checklists des recomandation webperf
<li><a data-start="3030">50:30</a> : sprites ou encodage des images ?
<li><a data-start="3330">55:30</a> : les images en PNG
<li><a data-start="3420">57:00</a> : gzip
<li><a data-start="3540">59:00</a> : interlude
<li>Outils</li>
<ul>
<li><a data-start="3630">1:00:30</a> : firebug, ySlow, pageSpeed et cuzillion.org
<li><a data-start="3780">1:03:50</a> : démo (plantée) de AOL pageTest et fallback sur webpagetest.org
<li><a data-start="4050">1:07:30</a> : aparté sur les cookies
<li><a data-start="4290">1:11:30</a> : Speed tracer
<li><a data-start="4460">1:14:20</a> : dynatrace AJAX
<li><a data-start="4500">1:15:00</a> : mot clé debugger
<li><a data-start="4590">1:16:30</a> : IE8 debug tools (démo plantée)
	</ul>
<li>Questions</li>
<ul>
<li><a data-start="4770">1:19:30</a> : question sur les commentaires conditionnels
<li><a data-start="4950">1:22:30</a> : remarque sur l&rsquo;importance du server-side ?
<li><a data-start="5070">1:24:30</a> : remarque sur le PNG et l&rsquo;encodage de JS
	</ul>
</ul>
<div id="container-player-atelier-perf">
    <a href="http://www.dailymotion.com/video/xguqi5">Vous trouverez la vidéo en ligne sur dailymotion</a>
</div>
<p><script>
var	sPlayerId = 'player-atelier-perf',
	oPlayer,
	playList = document.getElementById('playlist').getElementsByTagName('A');
BC.loadJS('http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js', function() {
	var	params = { allowScriptAccess: "always" },
		atts = { id: sPlayerId };
	swfobject.embedSWF('http://www.dailymotion.com/swf/xguqi5?enableApi=1&#038;playerapiid='+sPlayerId,
                       'container-'+sPlayerId, "600", "400", "9", null, null, params, atts);
});
var onTimeClick = function() {
	oPlayer.seekTo( this.getAttribute('data-start') );
};
function onDailymotionPlayerReady() {
	oPlayer = document.getElementById(sPlayerId);
	for(var i=0; i < playList.length; i++) {
		playList[i].onclick = onTimeClick;
	}
};
</script></p>
<p>Je remercie en tout cas l'organisation sans faille de Paris Web, le caméramen qui a bien filmé les zones intéressantes de l'écran projeté et le monteur de la vidéo !
</p>
<p><!--<br />
<iframe frameborder="0" width="560" height="448" src="http://www.dailymotion.com/embed/video/xguqi5?width=560&#038;theme=eggplant&#038;foreground=%23CFCFCF&#038;highlight=%23834596&#038;background=%23000000&#038;start=&#038;animatedTitle=&#038;iframe=1&#038;additionalInfos=0&#038;autoPlay=0&#038;hideInfos=0"></iframe><br /><b><a href="http://www.dailymotion.com/video/xguqi5_atelier-performance-web-jean-pierre-vincent_tech">[Atelier] Performance Web (Jean-Pierre Vincent)</a></b><br />
--></p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/braincracking?a=IK55nE_4wac:0VIj0PE6YNs:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/braincracking?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=IK55nE_4wac:0VIj0PE6YNs:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/braincracking?i=IK55nE_4wac:0VIj0PE6YNs:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=IK55nE_4wac:0VIj0PE6YNs:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/braincracking?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=IK55nE_4wac:0VIj0PE6YNs:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/braincracking?i=IK55nE_4wac:0VIj0PE6YNs:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=IK55nE_4wac:0VIj0PE6YNs:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/braincracking?i=IK55nE_4wac:0VIj0PE6YNs:V_sGLiPBpWU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/braincracking/~4/IK55nE_4wac" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://braincracking.org/2011/02/03/conference-performance-a-paris-web-2010/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<feedburner:origLink>http://braincracking.org/2011/02/03/conference-performance-a-paris-web-2010/</feedburner:origLink></item>
		<item>
		<title>HTML5 et le Web ouvert, pour les aigris et les cyniques</title>
		<link>http://feedproxy.google.com/~r/braincracking/~3/NoadkxTpRtM/</link>
		<comments>http://braincracking.org/2011/01/29/html5-et-le-web-ouvert-pour-les-aigris-et-les-cyniques/#comments</comments>
		<pubDate>Sat, 29 Jan 2011 21:33:59 +0000</pubDate>
		<dc:creator>jpvincent</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[opinion]]></category>

		<guid isPermaLink="false">http://braincracking.org/?p=764</guid>
		<description><![CDATA[L&#8217;actualité récente autour de HTML5 a fait réagir beaucoup de développeurs, ce qui à tout le moins permet d&#8217;avoir un instantané des opinions de la communauté Web. Elle vont de l&#8217;inutilité d‘avoir un logo aux affirmations du type “HTML5 ne me concerne pas car je supporte IE6”. Ceux qui participent au débat sont soit enthousiastes soit [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.w3.org/html/logo/downloads/HTML5_Logo_128.png" style="float:right" alt="" /><br />
L&rsquo;actualité récente autour de <abbr>HTML5</abbr> a fait réagir beaucoup de développeurs, ce qui à tout le moins permet d&rsquo;avoir un instantané des opinions de la communauté Web. Elle vont de l&rsquo;inutilité d‘avoir un <a href="http://www.w3.org/html/logo/">logo</a> aux affirmations du type “<abbr>HTML5</abbr> ne me concerne pas car je supporte <abbr>IE6</abbr>”. Ceux qui participent au débat sont soit enthousiastes soit <strong>aigris</strong> par la réalité de leur travail. Ceux qu‘on ne voit pas parler sont les <strong>blasés</strong>. Ce post d‘opinion, plutôt inhabituel sur ce blog technique, s‘adresse à ces 2 dernières catégories : <strong>pourquoi soutenir ou même s‘intéresser à l‘extension des technologies du Web en général, et au mouvement HTML5 en particulier</strong> ?<br />
<span id="more-764"></span></p>
<h2>Un peu de machiavélisme</h2>
<p>Mettons de côté les principes philosophiques d&rsquo;un web ouvert : soit vous y adhérez déjà par principe, soit ça vous en touche une sans faire bouger l&rsquo;autre auquel cas il est bon de se rappeler ce que le Web ouvert peut vous apporter personnellement.</p>
<h3>Ca n&rsquo;appartient à personne</h3>
<p>On peut remercier Apple pour nous avoir démontré avec Objective-C et les applications iOS tous les désavantages liés aux langages et processus de distributions fermés. C&rsquo;est un succès commercial et les utilisateurs sont heureux, alors pourquoi est ce que les développeurs joueraient les rabats-joie ?</p>
<ul>
<li>Outils et langage imposés, parfois payants</li>
<li>Une autorité arbitraire peut décider unilatéralement que votre application ne sera pas visible ou doit fermer</li>
<li>La même autorité peut décider que votre business model ne lui convient pas (voir le cas de <a href="http://www.igeneration.fr/ipad/presse-sur-ios-apple-serre-la-vis-30482">la presse belge</a>)</li>
<li>Si la communauté est petite, la formation sera chère. Les infos pour développer sur iOS sont monnaie courante, mais il est difficile de trouver des infos pour les autres plate-formes</li>
</ul>
<h3>Le multi-plateforme arrive</h3>
<p>Ca m&rsquo;ennuie de le reconnaître, mais le Web à partir du bureau devient l&rsquo;exception plutôt que la règle, en particulier lorsque l&rsquo;on regarde les statistiques mondiales. Depuis plusieurs années déjà il y a plus d&rsquo;internautes sur mobile que sur bureau, et dans les pays en voie de développement c&rsquo;est même l&rsquo;unique usage du Web. Certes pour ces pays ça n&rsquo;est pas du smartphone mais ça viendra. Dans l&rsquo;occident, l&rsquo;usage du Web depuis différents terminaux est maintenant courant et se fait selon la fonctionalité et les conditions pratiques : le mobile pendant les pauses, les éventuels trajets ou le soir au lit pour vérifier son facebook et ses mails, le PC au bureau et à la maison pour du e-commerce par exemple.</p>
<p>Hors dans l&rsquo;ère pré-iPhone il fallait savoir coder en java ou pire dans des langages propriétaires pour faire des applications. Apple a imposé l&rsquo;Objective-C, Android et d&rsquo;autres sont restés sur java. Je n&rsquo;ai rien contre java, mais pourquoi j&rsquo;apprendrais un nouveau langage si j&rsquo;ai la possibilité de capitaliser sur ce que je connais déjà ? Et quelles sociétés <a href="http://www.pagesjaunes.fr/plusdeservices/groupepagesjaunes/surmonmobile.do">hormis les pages jaunes</a> peuvent se payer de construire et maintenir la même applications sur une dizaine de plate-formes mobiles différentes ?</p>
<p>Il est déjà possible de construire des applications Web qui tournent très bien sur la majorité des webkits mobiles, et aujourd&rsquo;hui ces sites-applications peuvent se passer d&rsquo;une connexion au net (Offline, Web Storage), peuvent parfois avoir accès aux capacités matérielles du mobile (la géolocalisation) et peuvent être “installés”.</p>
<p>Le W3C est en train <a href="http://www.w3.org/2009/dap/#history">de spécifier</a> de quoi accéder à beaucoup plus de matériel (SMS, contacts, caméra, fichiers locaux &#8230;), avec le concours de Nokia, Ericson ou Vodafone. Il y a donc un espoir pour qu&rsquo;une application Web ait les mêmes possibilités qu&rsquo;une application native. Pousser dans le sens des standards du Web, c&rsquo;est donc aussi se donner la possibilité de pouvoir changer de branche ou d&rsquo;utiliser la même équipe de développeurs pour faire du Web desktop, mobile et de l&rsquo;applicatif mobile.</p>
<h3>La concurrence, c&rsquo;est bon, mangez en</h3>
<p>Pourquoi les technos du Web devraient elles s‘attaquer au mobile voire au software ? Il existe déjà de très bons langages avec de très bons frameworks et de très bons développeurs dans ces domaines. Sauf que le manque de concurrence dans la technologie est très dangereuse, même si elle entraîne des difficultés pour les développeurs. Souvenez vous comme c‘était pratique pour les développeurs Web de voir <abbr title="Internet Explorer 6">IE6</abbr> gagner la première <span lang="en">Browser War</span>. En ces temps heureux pendant 1 ou 2 ans, beaucoup ont eu le sentiment qu&rsquo;ils pouvaient ne tester qu&rsquo;un seul navigateur et ignorer les autres (Safari Mac, Lynx &#8230;). Et puis Firefox est arrivé, a grandi et a forcé Microsoft à s&rsquo;engager, négocier puis bientôt respecter les standards du Web. Le projet Webkit a survécu et a facilité l&rsquo;arrivée de Chrome et des Webkits sur mobiles. Opéra a testé un business model et a fourni de bonnes idées à tout le monde.</p>
<p>Bref la concurrence entre navigateurs a fait que l&rsquo;expérience utilisateur en général s&rsquo;est améliorée. La situation pour les développeurs Web s‘est compliquée d‘une certaine manière, puisqu‘il y a une bonne dizaine de <a title="Tester avec fiabilité les navigateurs" href="http://braincracking.org/?p=614">navigateurs à tester</a>. Cette complexité est compensée par la maturité grandissante des développeurs et des librairies. Que se serait il passé si Microsoft était resté à 90% de part de marché ces 10 dernières années ? L‘accès aux technos du Web serait sans doute plus complexe (essayez de lire <a title="documentation sur dropEffect" href="http://msdn.microsoft.com/en-us/library/ms533741(VS.85).aspx">la MSDN</a>), voire payante comme l‘est <a title="inscription développeur Apple" href="http://developer.apple.com/programs/which-program/">le développement iOS</a>.</p>
<p>Même en regardant le processus d‘écriture des specs, le fait d‘avoir 2 organisations a déjà eu des effets positifs, et on espère que l&rsquo;émulation va continuer. Après le schisme de 2004, le WHATWG (originellement Apple, Mozilla et Opéra) avait travaillé sur ces spécifications :</p>
<ul>
<li>WebForms 2, qui améliore l&rsquo;interface des formulaires natifs</li>
<li>Web Storage, pensé comme un super cookie</li>
<li>Web Socket et Server Sent Event qui permettent une communication plus efficace entre le client et le serveur</li>
</ul>
<p>En résumé : ils se sont concentrés sur ce qui pouvait être utile aux développeurs d&rsquo;application Web dans l&rsquo;immédiat et se sont lancés dans le même temps dans l&rsquo;implémentation dans les navigateurs. On n&rsquo;est peut être pas dans la révolution technologique (les formulaires sont émulables en Javascript, le reste avec Flash), mais cette marche forcée du HTML vers les “applications Web” est très positive, car elle nous donne plus de pouvoir, et certaine API comme “Web Workers” sont très innovantes.</p>
<h2>Un peu de pragmatisme</h2>
<p>En attendant le mobile, voyons déjà ce qu&rsquo;on peut faire des nouveautés sur navigateur desktop, avec notamment les apports de HTML5. Ce qui compte pour un développeur au moment de faire ses choix techniques, c‘est l‘état d‘implémentation de chaque API JavaScript par les navigateurs ou, pour la partie sémantique, de savoir quels sont les <span lang="en">user-agent</span> qui savent exploiter le nouveau balisage.</p>
<h3>Sémantique </h3>
<p>Côté sémantique, la politique des lecteurs d‘écran est probablement la même que celle du moteur Google : s‘adapter à ce que font la majorité des sites (<a href="http://www.google.com/support/forum/p/Webmasters/thread?tid=2d4592cbb613e42c&#038;hl=en">source</a> : un community manager de Google). Si les webmasters se mettent à utiliser <code>nav</code> ou <code>article</code>, ils suivront. Les navigateurs seront sans doute un peu plus pro-actifs pour proposer des fonctionalités tirant parti de l‘analyse des balises (un <a href="http://www.apple.com/fr/safari/whats-new.html#reader">lecteur d‘article</a> comme Safari par exemple). Dans les 2 cas, suivre les balises standards (et éviter d‘en inventer) c‘est se donner une <strong>longueur d‘avance sur les concurrents</strong> pour un coût de développement négligeable.</p>
<h3>les APIs</h3>
<p>Côté APIs (Web apps selon le <abbr>WHATWG</abbr>) il ne faut pas prendre <abbr>HTML5</abbr> comme un bloc mais partir de la fonctionnalité souhaitée et regarder quelles sont les <abbr>APIs</abbr> qui peuvent vous être utiles. La plupart du temps, la fonctionnalité est simulable en JavaScript ou en Flash, et un <a href="https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-browser-Polyfills">certain nombre</a> de petites librairies (ou polyfills, si l‘usage <a href="http://remysharp.com/2010/10/08/what-is-a-polyfill/">du terme</a> prend) permettent d‘y accéder sans trop de problèmes. L‘intérêt fonctionnel est de proposer une meilleure expérience à la moitié de vos utilisateurs qui ont des navigateurs au niveau, et une fonctionnalité qui marche pour les autres.<br />
Au niveau du code, les spécifications n‘étant pas réservées aux implémentation navigateur, l‘API est généralement également suivie par ces <span lang="en">polyfills</span>. Lors d‘un changement de projet, de librairie, ou lorsque vous passerez à l‘utilisation exclusive de la fonctionnalité en natif, vous retrouverez les mêmes signature de fonction et la même structure de code.</p>
<p>J‘ai fait une conférence entière à Paris Web 2010 sur ce sujet, je vous invite à regarder <a href="http://braincracking.org/?p=597">les slides</a> pour vous forger une opinion sur le déploiement possible en production.</p>
<h2>Mais que faire John ?</h2>
<p>Au niveau individuel, pour aider à tout cela, c‘est autant une affaire d‘expertise technique que de savoir vendre en interne ces technologies. Formez vous, faîtes votre veille techno, participez aux réunions produit ou faîtes des démos en interne utilisant vos nouvelles connaissances : ça égaie le travail et vous donnera l‘impression salutaire d‘être un peu plus qu‘un cracheur de code.<br />
Un engagement un peu plus fort pourrait aussi consister à signaler des bugs aux navigateurs, à ceux qui font des librairies open-source ou des outils vous permettant de transposer vos compétences Web sur mobile ou desktop.<br />
Enfin vous pouvez également contribuer au code open source ou participer aux discussions W3C ou WHATWG, ils sont réellement dans l‘attente des avis des développeurs Web pour progresser!</p>
<p>Au niveau de la communauté, je pense qu‘une initiative du W3 comme ce logo reste positive, tant que la discussion avec la communauté est ouverte (le logo ne sera officiel que début 2011) et que le message n‘est pas brouillé (une phrase heureusement retirée incluait CSS3, WOFF et SVG dans HTML5). Beaucoup de développeurs seront heureux d‘avoir une bannière à laquelle se rallier et tant pis pour ceux qui accusent le W3C de vouloir faire du marketing. Demandez à la fondation Mozilla si le marketing sert ou dessert la cause du libre.<br />
A propos de brouiller le message, je ne pense pas que la décision du WHATWG d‘abandonner HTML5 et de parler de “living standard“ et de “web application” soit la bonne. Concernant le terme HTML5, on pourra se limiter à la spec du W3C, préciser quelles APIs on y inclue ou bien en parler à tort et à travers : comme “AJAX”, tout est fonction de votre interlocuteur.</p>
<h2>Conclusion</h2>
<p>Pourquoi pousser dans le sens du Web ouvert notamment avec HTML5 et les APIs associées ?</p>
<ul>
<li>pour jouer le jeu de la concurrence et placer le tryptique Javascript/HTML/CSS  au backend, dans des applications de bureau ou sur mobile
<li>pour les sociétés du Web, la possibilité de ré-utiliser les compétences et les outils en interne pour attaquer d&rsquo;autres domaines
<li>pour les développeurs, plus de possibilités de carrière, plus de nouveautés, bref que du bonheur
<li>l‘accès à de nouvelles fonctionnalité est plus facile, ce qui permet d‘avoir une longueur d‘avance sur les concurrents
<li>les standards même en construction facilitent la réutilisabilité et la maintenance du code
</ul>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/braincracking?a=NoadkxTpRtM:ydQc3FhxDcw:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/braincracking?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=NoadkxTpRtM:ydQc3FhxDcw:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/braincracking?i=NoadkxTpRtM:ydQc3FhxDcw:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=NoadkxTpRtM:ydQc3FhxDcw:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/braincracking?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=NoadkxTpRtM:ydQc3FhxDcw:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/braincracking?i=NoadkxTpRtM:ydQc3FhxDcw:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=NoadkxTpRtM:ydQc3FhxDcw:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/braincracking?i=NoadkxTpRtM:ydQc3FhxDcw:V_sGLiPBpWU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/braincracking/~4/NoadkxTpRtM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://braincracking.org/2011/01/29/html5-et-le-web-ouvert-pour-les-aigris-et-les-cyniques/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		<feedburner:origLink>http://braincracking.org/2011/01/29/html5-et-le-web-ouvert-pour-les-aigris-et-les-cyniques/</feedburner:origLink></item>
		<item>
		<title>Retour sur le Concours Webperf 2010</title>
		<link>http://feedproxy.google.com/~r/braincracking/~3/1j7v8WPyGo8/</link>
		<comments>http://braincracking.org/2011/01/10/retour-sur-le-concours-webperf-2010/#comments</comments>
		<pubDate>Mon, 10 Jan 2011 11:04:33 +0000</pubDate>
		<dc:creator>jpvincent</dc:creator>
				<category><![CDATA[Performances]]></category>
		<category><![CDATA[concours webperf 2010]]></category>
		<category><![CDATA[Perfs]]></category>

		<guid isPermaLink="false">http://braincracking.org/?p=717</guid>
		<description><![CDATA[Durant tout novembre 2010 a eu lieu le premier concours international de performance Web. Je vous renvoie vers ce post d&#8217;introduction si vous n&#8217;en aviez pas entendu parler. Le principe était relativement simple : afficher une page le plus rapidement possible. Pour cela la FNAC nous a gentiment prêté son nom, et une page cible. [...]]]></description>
			<content:encoded><![CDATA[<p>Durant tout novembre 2010 a eu lieu le premier <a href="http://webperf-contest.com/index-fr.html">concours international de performance Web</a>. Je vous renvoie vers <a href="http://braincracking.org/?p=607">ce post d&rsquo;introduction</a> si vous n&rsquo;en aviez pas entendu parler. Le principe était relativement simple : afficher une page le plus rapidement possible. Pour cela la FNAC nous a gentiment prêté son nom, et une page cible.</p>
<p><span id="more-717"></span></p>
<p>Nous avons reproduit cette page via des fichiers statiques et les concurrents ont pu modifier les sources sur un serveur commun. Résultats ? la page de base mettait <strong>4-5 secondes avant de commencer à afficher quelque chose d&rsquo;utile</strong> et <strong>plus de 15s pour récupérer complètement la page</strong>. Et on parle bien de <strong><a href="http://www.webpagetest.org/result/101203_0c152afe6dab2cb3efbd674e32bcb6da/4/details/">la version statique</a></strong> : pas de script côté serveur, pas de requête SQL, bref aucun ralentissement de côté là.</p>
<figure>
	<video controls width="610"  autobuffer preload=”auto”><br />
	<source src="http://vid.ly/1l4c0t?content=video" /><br />
	<a href="http://94.23.51.58/jpvincent/blog/wp-content/uploads/2011/01/filmstrip.png"><img class="size-large wp-image-704" title="filmstrip" src="http://94.23.51.58/jpvincent/blog/wp-content/uploads/2011/01/filmstrip-1024x82.png" alt="" width="614" height="49" /></a><br />
</video></p>
<figcaption>Comparaison du rendu progressif entre la page statique originale et les pages des 3 gagnants</figcaption>
</figure>
<h2>Mais comment font ils ?</h2>
<p>Afin de contribuer à répandre la bonne parole sur les performances Web, et pour nous aider à les juger, chaque candidat avait la responsabilité de noter les modifications qu&rsquo;il avait entrepris. Il y en a de toute beauté, mais il faut fouiller pour les trouver : il y en a 250 que <a href="http://webperf-contest.com/leaderboard-fr.html">vous retrouverez ici</a> dans la colonne Gist. Vous pouvez classer les concurrents par temps de rendu, nombre de requête, poids total et score YOTTAA pour voir ceux des finalistes</p>
<p>Il y a aussi un petit nombre de posts de blogs des participants que je vous conseille de lire :</p>
<ul>
<li><a href="http://www.yterium.net/Ma-participation-au-Webperf">l&rsquo;énorme post</a> du suractif Cédric Morin, à relire plusieurs fois tant certaines techniques sont géniales. On y apprend aussi que le projet SPIP va bénéficier de cette expérience, qu&rsquo;il en a profité pour lancer JQI, un lazy-loader de jQuery et qu&rsquo;il contribue à CSSTidy</li>
<li>un <a href="http://entries.webperf-contest.com/4cd41a2537c1a/gist.html">retour tout aussi détaillé</a> de <a href="http://twitter.com/pixelastic">Timothée Carry-Caignon</a> sur son travail, avec notamment un bug de &lt;noscript&gt; et pas mal de travail sur JS</li>
<li>un <a lang="en" href="http://tips.freedev.com.ar/en/wpo/faster-sprite-download/">court article</a> d&rsquo;un développeur espagnol spécialisé dans la performance Web, qui dit tout le bien qu&rsquo;il y a à précharger ses sprites en JS dans le head avant d&rsquo;y faire référence dans le CSS . Pas sur que l&rsquo;idée soit géniale.</li>
</ul>
<p><strong>Ex-concurrent ? : contribuez vous aussi</strong> : si vous avez le sentiment d&rsquo;avoir essayé une technique qui vaut qu&rsquo;on parle d&rsquo;elle car elle est <strong>peu connue mais efficace</strong> ou au contraire <strong>connue mais décevante</strong>, bloguez dessus ou <a href="http://braincracking.org/a-propos/">écrivez moi</a> ! Ca fera peut être l&rsquo;objet d&rsquo;un post complémentaire</p>
<h2>Je n&rsquo;ai pas la journée &#8230;</h2>
<p>Moi non plus, donc j&rsquo;ai pris plusieurs soirées : faisant partie du jury, j&rsquo;ai du passer du temps à analyser le travail de la quinzaine de finalistes (ceux qui avaient le meilleur score calculé automatiquement). En passant j&rsquo;avais préparé ces articles, que je n&rsquo;ai mis en forme que récemment, et divisé en une série de 3 posts qui résument globalement les techniques utilisées :</p>
<nav>
<ol>
<li><a href="http://braincracking.org/?p=695">Les bases</a>. Configurer Apache, réduire le poids</li>
<li><a href="http://braincracking.org/?p=617">Maîtriser le chargement</a>. L&rsquo;essentiel de l&rsquo;effort pendant le concours : charger images, JS et CSS, lazy-loading, defer, inline, parallélisation, MHTML et data:uri</li>
<li><a href="http://braincracking.org/?p=696">Refactoring, enseignements</a>. Les bonnes pratiques de Développement Web ont eu le dernier mot sur les perfs ! Egalement le résumé des <strong>enseignements techniques</strong> du concours</li>
</ol>
</nav>
<p>Ce n&rsquo;est qu&rsquo;une vue partielle et ça ne sera jamais que mon opinion mais devant la somme de travail et le nombre d&rsquo;avis divergents potentiels, je ne peux que vous demander de réagir en commentaire, par mail ou par blog, afin que la communauté en bénéficie</p>
<h2>Bilan sur le concours lui même</h2>
<p>0 retour presse, preuve que la performance Web est loin de l&rsquo;oeil de la presse informatique généraliste. Mais nous avons tout de même eu 250 inscrits dont 55 ont réellement participé. Aux deux tiers français de par l&rsquo;influence d&rsquo;Eric Daspet et <a href="http://www.alsacreations.com/actu/lire/1147-concours-international-de-performance-web.html">Alsacreations</a>, ce chiffre est tout de même largement supérieur à nos attentes (honnêtement j&rsquo;aurai déjà été heureux avec une vingtaine de français&#8230;). J&rsquo;interprète ce bon résultat comme le signe que les développeurs Web commencent à envisager avec autant de sérieux les techniques de performance Web que l&rsquo;accessibilité ou le bon usage des CSS.</p>
<ul>
<li>la charge de travail était énorme : ceux qui ont été finalistes ont consacré plus de 30h sur cette page ! Certains ont abandonné après avoir vu le nombre de fichiers et la taille du <abbr>HTML</abbr>, et d&rsquo;autres en <a href="http://razorfast.com/2010/12/02/why-i-didnt-try-to-win-webperf-contest-2010/">en cours de route</a>. Pour être honnête nous ne nous attendions pas à ce volume de travail. Rassurez vous, nous avons passé autant de temps à l&rsquo;organiser puis à le juger.</li>
<li>malgré cela, je maintiens que cette page était parfaite car complètement représentative des pages du Web d&rsquo;aujourd&rsquo;hui : un long historique, des fonctionnalités qui s&rsquo;accumulent, des compétences variées qui travaillent le même code avec différents niveaux de qualité &#8230; Les poids, le nombre de requêtes et les temps de chargement sont dans les moyennes mondiales</li>
<li>beaucoup de concurrents, c&rsquo;est beaucoup d&rsquo;essais différents, et donc beaucoup de validation / invalidation de techniques. Je pense sérieusement que c&rsquo;est bon pour les connaissances globales sur les performances Web</li>
<li>même les concurrents qui ont abandonné très tôt ont dit avoir appris des choses, ce qui était le but premier. Ne serait ce que de mettre les mains dans le cambouis et se poser des questions qu&rsquo;on n&rsquo;a pas le temps ou l&rsquo;envie de se poser au travail, c&rsquo;est ça qui fait de vous autre chose qu&rsquo;une <abbr title="pisseur de code">dactylo-codeuse</abbr></li>
<li>du code open-source a été amélioré ou créé, grâce à l&rsquo;infatiguable Cédric Morin : Spip, <a lang="en" href="https://github.com/Cerdic/CSSTidy">CSSTidy</a>, <a lang="en" href="https://github.com/Cerdic/jQl">jQueryLoader</a></li>
<li>nous avons testé les limites de <abbr>YOTTAA</abbr> (un bug trouvé et corrigé) et de WebpageTest.org</li>
</ul>
<p>Vous retrouverez un bilan plus technique dans <a href="http://braincracking.org/?p=696">le dernier post</a>.</p>
<p>Bravo à l&rsquo;organisateur principal <a href="http://zeroload.net/" title="consultant performance web">Zeroload</a> qui a eu l&rsquo;idée et qui a consacré le plus de temps à ce projet. Bravo également à tous les concurrents que je n&rsquo;ai pas cité dans les différents posts, ça n&rsquo;était pas facile mais vous comme les autres en retireront une meilleure connaissance. Merci à mes collègues juges <a href="http://eric.daspet.name/">Eric Daspet</a> et <a href="http://www.phpied.com/category/performance/">Stoyan Stefanov</a> et enfin Merci à nos sponsors <a href="http://www.yottaa.com/" title="web performance tools ">YOTTA</a>, <a href="http://www.catchpoint.com/">Catchpoint System</a> et <a href="http://www.alwaysdata.com/" title="hébergement">Always Data</a> d&rsquo;avoir fourni hébergement et lots</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/braincracking?a=1j7v8WPyGo8:de-ZugidCJ0:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/braincracking?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=1j7v8WPyGo8:de-ZugidCJ0:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/braincracking?i=1j7v8WPyGo8:de-ZugidCJ0:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=1j7v8WPyGo8:de-ZugidCJ0:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/braincracking?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=1j7v8WPyGo8:de-ZugidCJ0:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/braincracking?i=1j7v8WPyGo8:de-ZugidCJ0:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=1j7v8WPyGo8:de-ZugidCJ0:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/braincracking?i=1j7v8WPyGo8:de-ZugidCJ0:V_sGLiPBpWU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/braincracking/~4/1j7v8WPyGo8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://braincracking.org/2011/01/10/retour-sur-le-concours-webperf-2010/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		<feedburner:origLink>http://braincracking.org/2011/01/10/retour-sur-le-concours-webperf-2010/</feedburner:origLink></item>
		<item>
		<title>Concours Webperf 2010 : les bases</title>
		<link>http://feedproxy.google.com/~r/braincracking/~3/uDqd4fleDXk/</link>
		<comments>http://braincracking.org/2011/01/10/concours-webperf-2010-les-bases/#comments</comments>
		<pubDate>Mon, 10 Jan 2011 11:03:38 +0000</pubDate>
		<dc:creator>jpvincent</dc:creator>
				<category><![CDATA[Performances]]></category>
		<category><![CDATA[concours webperf 2010]]></category>
		<category><![CDATA[Perfs]]></category>

		<guid isPermaLink="false">http://braincracking.org/?p=695</guid>
		<description><![CDATA[Ce post est le premier d&#8217;une série de 3 et est tiré de l&#8217;expérience des finalistes du concours de performance Web 2010 Les bases Maîtriser le chargement. Refactoring, enseignements. Il traite rapidement des actions classiques en Performances Web qui sont les plus faciles à mettre en place tout en offrant un retour sur investissement souvent [...]]]></description>
			<content:encoded><![CDATA[<p>Ce post est le premier d&rsquo;une série de 3 et est tiré de l&rsquo;expérience des finalistes du concours de performance Web 2010</p>
<nav>
<ol>
<li>Les bases</li>
<li><a href="http://braincracking.org/?p=617">Maîtriser le chargement</a>.</li>
<li><a href="http://braincracking.org/?p=696">Refactoring, enseignements</a>.</li>
</ol>
</nav>
<p>Il traite rapidement des actions classiques en Performances Web qui sont les plus faciles à mettre en place tout en offrant un retour sur investissement souvent suffisant. Il devrait être utile aux novices mais ceux qui connaissent déjà les bases devraient aller voir les 2 articles suivants.<br />
<span id="more-695"></span></p>
<h2>La configuration d&rsquo;Apache</h2>
<p>Les premières actions pour améliorer à peu de frais et de manière impactante les performances Web passent par la configuration de son serveur Web. Si vous voulez un exemple complet, regardez <a href="http://entries.webperf-contest.com/4ce63091aafd1/sources/htaccess.txt">ce .htaccess</a>, fait par <a href="http://twitter.com/omarnetfr">Omar Haddouchi</a>, qui a fait par ailleurs un <a href="https://gist.github.com/22fbd663646947a3d3ba">boulot impressionant</a>. Il y a principalement 3 actions :</p>
<h3>Gérer le cache navigateur</h3>
<p>Il s&rsquo;agit de demander au navigateur de garder chez lui autant que possible les fichiers statiques. Non les techniques à base de <a href="http://en.wikipedia.org/wiki/HTTP_ETag">ETag</a> et de réponse 304 sont quasiment inutiles car une requête <abbr>HTTP</abbr> est tout de même faite pour vérifier la fraîcheur du fichier. Et sur des fichiers de page Web, généralement entre 1 et 200Ko, l&rsquo;aller-retour au serveur seul est plus long que le téléchargement. Voici un exemple de configuration :</p>
<pre><code>&lt;IfModule mod_expires.c&gt;
	ExpiresActive On
	ExpiresDefault "access plus 1 month"
	ExpiresByType image/jpeg "access plus 1 month"
# ../..
	ExpiresByType text/javascript "access plus 1 month"
&lt;/IfModule&gt;
</code></pre>
<p>Un mois ça n&rsquo;est pas encore assez agressif, la valeur généralement <a href="http://developer.yahoo.com/performance/rules.html#expires">recommandée</a> est de 10 ans <img src='http://braincracking.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Par contre cela demande une très bonne gestion (dynamique donc) des URLs qui mènent aux fichiers statiques, afin de faire recharger les <abbr>JS/CSS/</abbr>images que vous mettez à jour.</p>
<h3>La compression <abbr>Gzip</abbr></h3>
<p>Compresser à la volée les fichiers non binaires (<abbr>HTML, CSS, JS</abbr>) vous épargne d&rsquo;envoyer 80% de leurs poids sur votre réseau, et aide vos utilisateurs à petit débit (à l&rsquo;étranger, sur mobile, un <a href="http://royal.pingdom.com/2010/11/12/real-connection-speeds-for-internet-users-across-the-world/">petit pourcentage</a> de français). Compresser du binaire est généralement inutile et consommateur de ressources serveur, d&rsquo;où cette configuration :</p>
<pre><code>&lt;IfModule mod_gzip.c&gt;
	mod_gzip_on       yes
	mod_gzip_dechunk  yes
	mod_gzip_item_include file      .(html|txt|css|js|json)$
	mod_gzip_item_exclude file      .(jpg|png|gif|ico)$
&lt;/IfModule&gt;
</code></pre>
<p>Vous pouvez aller encore plus loin avec gzip et ne pas faire faire la compression par Apache à chaque requête mais plutôt en générant des fichiers gzipés (au build, ou de manière dynamique) de vos HTML (si la page est statique) et CSS/JS et en servant cette version si le navigateur le supporte. Voici un exemple de configuration :</p>
<pre><code>
# déclaration des types des fichiers gzipés
AddType "application/javascript" .jsgz
AddType "text/css" .cssgz
AddType "text/html" .htmlgz
# ajout de l'entête gzip pour ces fichiers
AddEncoding gzip .jsgz
AddEncoding gzip .cssgz
AddEncoding gzip .htmlgz
</code></pre>
<p>Cet exemple est pris du <code>.htaccess</code> de <a href="ftp://ftp.alwaysdata.com/entries/4ccbf6fa4c539/.htaccess">Etienne Guilluy</a>. Dans le cadre du concours, l&rsquo;intérêt était limité, mais en production l&rsquo;avantage est évident car il permet d&rsquo;épargner du CPU et donc de mieux résister aux charges.</p>
<h3>Supprimer les <span lang="en">cookies</span> inutiles</h3>
<p>Un <span lang="en">cookie</span> fait entre 0.5 et 4ko. Une page moyenne déclenche une cinquantaine de requêtes (115 sur cette page de la FNAC &#8230;). Si vous n&rsquo;y prenez pas garde vous allez donc demander à votre utilisateur d&rsquo;uploader chez vous entre 25Ko et 200Ko (le double donc pour la FNAC) alors que le cookie n&rsquo;est généralement utile que pour la partie dynamique qui génère le <abbr>HTML</abbr>, et que l&rsquo;upload des <abbr>ADSL</abbr> beaucoup plus précieux que le download.</p>
<p>La technique consiste à mettre ses fichiers statiques sur un autre nom de domaine ou sous-domaine et à ne pas activer les cookies. Pour ce concours, nous fournissions des sous-domaines, mais il fallait penser à remplacer la définition du cookie sur le domaine faite en JS dans le marqueur pour en bénéficier complètement.</p>
<h2>Le poids des images</h2>
<p>et le choc des mots&#8230; Mais je m&rsquo;égare <img src='http://braincracking.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  L&rsquo;avantage de ce concours, c&rsquo;est que certains ont pu revisiter les images de la FNAC qui comme sur beaucoup de sites sont fabriquées à la chaîne, sans optimisation particulière. Plusieurs concurrents ont donc réduit le poids des images avec les techniques suivantes :</p>
<ul>
<li>réduction de la palette de couleurs pour les <abbr>PNG</abbr> 8 bits</li>
<li><span lang="en">indexed colors</span> pour les images de moins de 256 couleurs</li>
</ul>
<h2>Optimisation du CSS</h2>
<h3>Automagique</h3>
<p>La technique générale a été de générer une version &laquo;&nbsp;de production&nbsp;&raquo; par un outil, en voici plusieurs :</p>
<ul>
<li><a lang="en" href="http://csstidy.sourceforge.net/">CSS Tidy</a> pour le compresser</li>
<li>l&rsquo;<span lang="en">addon</span> Firefox <a lang="en" href="https://addons.mozilla.org/en-US/firefox/addon/10704/">css-usage</a> pour ne récupérer que les <abbr>CSS</abbr> utilisés</li>
</ul>
<p>Il n&rsquo;y a pas vraiment d&rsquo;outil meilleur que l&rsquo;autre en terme de performance pure (poids final et rendu). Prenez donc celui qui s&rsquo;adapte le mieux à votre environnement de mise en production (vous en avez un n&rsquo;est ce pas ?) et vérifiez bien que tous vos hacks restent compris.</p>
<p>Si dans le cadre du concours il était intelligent de réduire le <abbr>CSS</abbr> en supprimant les lignes inutilisées dans cette page, en environnement de production, c&rsquo;est forcément plus délicat</p>
<h3>A la main</h3>
<p>Dans les recommandations Google se trouve depuis le début un conseil sur <a href="http://code.google.com/intl/fr/speed/page-speed/docs/rendering.html#UseEfficientCSSSelectors">les sélecteurs CSS</a> qui permettent d&rsquo;accélérer le rendu. Théoriquement c&rsquo;est évident. Mais on va se parler franchement : je n&rsquo;ai jamais constaté ou lu que cela permettait de gagner quoi que ce soit de significatif ( &gt; 100ms).</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/braincracking?a=uDqd4fleDXk:sZ9Ct7kAJpQ:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/braincracking?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=uDqd4fleDXk:sZ9Ct7kAJpQ:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/braincracking?i=uDqd4fleDXk:sZ9Ct7kAJpQ:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=uDqd4fleDXk:sZ9Ct7kAJpQ:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/braincracking?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=uDqd4fleDXk:sZ9Ct7kAJpQ:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/braincracking?i=uDqd4fleDXk:sZ9Ct7kAJpQ:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=uDqd4fleDXk:sZ9Ct7kAJpQ:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/braincracking?i=uDqd4fleDXk:sZ9Ct7kAJpQ:V_sGLiPBpWU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/braincracking/~4/uDqd4fleDXk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://braincracking.org/2011/01/10/concours-webperf-2010-les-bases/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<feedburner:origLink>http://braincracking.org/2011/01/10/concours-webperf-2010-les-bases/</feedburner:origLink></item>
		<item>
		<title>Concours Webperf 2010 : maîtriser le chargement</title>
		<link>http://feedproxy.google.com/~r/braincracking/~3/jvopPO-rcvk/</link>
		<comments>http://braincracking.org/2011/01/10/concours-webperf-2010_le-chargement/#comments</comments>
		<pubDate>Mon, 10 Jan 2011 11:02:44 +0000</pubDate>
		<dc:creator>jpvincent</dc:creator>
				<category><![CDATA[Performances]]></category>
		<category><![CDATA[concours webperf 2010]]></category>
		<category><![CDATA[Perfs]]></category>

		<guid isPermaLink="false">http://braincracking.org/?p=617</guid>
		<description><![CDATA[Ce post est le second d&#8217;une série de 3 et est tiré de l&#8217;expérience des finalistes du concours de performance Web 2010 Les bases Maîtriser le chargement. Refactoring, enseignements. Nous allons analyser les stratégies et techniques gagnantes (ou perdantes parfois) de chargement des dépendances de la page (CSS, JS, images, XHR). C&#8217;est là dessus que [...]]]></description>
			<content:encoded><![CDATA[<p>Ce post est le second d&rsquo;une série de 3 et est tiré de l&rsquo;expérience des finalistes du concours de performance Web 2010</p>
<nav>
<ol>
<li><a href="http://braincracking.org/?p=695">Les bases</a></li>
<li>Maîtriser le chargement.</li>
<li><a href="http://braincracking.org/?p=696">Refactoring, enseignements</a>.</li>
</ol>
</nav>
<p>Nous allons analyser les stratégies et techniques gagnantes (ou perdantes parfois) de chargement des dépendances de la page (CSS, JS, images, XHR). C&rsquo;est là dessus que se sont concentrés les finalistes car il n&rsquo;existe rien de suffisamment universel pour espérer gagner ce concours, nous avons donc assisté un joli combat de cerveaux.<br />
Ce post sera utile pour les développeurs Web qui pourront être inspirés pour accélérer le rendu de leurs propres pages, et d&rsquo;un intérêt tout particulier pour ceux qui connaissent déjà cette page.<br />
<span id="more-617"></span></p>
<h2>Charger ses <abbr>CSS/JS</abbr></h2>
<p>Toute la difficulté du <abbr>CSS</abbr>, c&rsquo;est que pendant qu&rsquo;il est téléchargé, le rendu est bloqué. On pourrait alors tout mettre inline (comme <a href="http://fr.yahoo.com/?p=us">la home de Yahoo</a>!), mais c&rsquo;est alors sacrifier les bénéfices du caching sur les fichiers statiques externes. Et le cache sur un cybermarchand est extrêmement utile puisqu&rsquo;on peut s&rsquo;attendre à ce qu&rsquo;un utilisateur visite plusieurs pages d&rsquo;affilé.</p>
<p>Tout est donc question de balance entre l&rsquo;<span lang="en">inline et l&rsquo;<span lang="en">external</span>, voici plusieurs stratégies :</span></p>
<h3>CSS différé</h3>
<p>L&rsquo;idée est de mettre le minimum de styles inline : un reset <abbr>CSS</abbr>, un peu du <span lang="en">header</span> et un préchargement d&rsquo;images, et charger en JavaScript le <abbr>CSS</abbr> externe. Malgré un <span lang="en">start render</span> au plus bas (200ms!), ceci déclenche malheureusement un <abbr title="Flash Of Unstyled Content">FOUC</abbr> désagréable le temps que le CSS final arrive.</p>
<div id="attachment_653" class="wp-caption alignleft" style="width: 160px"><a href="http://94.23.51.58/jpvincent/blog/wp-content/uploads/2010/12/delay-css-screenshot.jpg"><img class="size-thumbnail wp-image-653 " title="delay-css-screenshot" src="http://94.23.51.58/jpvincent/blog/wp-content/uploads/2010/12/delay-css-screenshot-150x150.jpg" alt="Screenshot Flash of Unstyled Content" width="150" height="150" /></a><p class="wp-caption-text">Contenu non stylé pendant 1s</p></div>
<div id="attachment_654" class="wp-caption alignright" style="width: 160px"><a href="http://94.23.51.58/jpvincent/blog/wp-content/uploads/2010/12/delay-css-screenshot2.jpg"><img class="size-thumbnail wp-image-654" title="delay-css-screenshot2" src="http://94.23.51.58/jpvincent/blog/wp-content/uploads/2010/12/delay-css-screenshot2-150x150.jpg" alt="" width="150" height="150" /></a><p class="wp-caption-text">Après 1s le contenu s&#39;affiche</p></div>
<p>Ces 2 <span lang="en">screenshots</span> sont extraits de <a href="http://www.webpagetest.org/video/compare.php?tests=101202_a392076e4536d5c6b687b12550aa0a60-r:6-c:0">cette série</a>. Vous pouvez tester cette technique sur vos navigateurs avec <a href="http://stevesouders.com/cuzillion/?c0=hs0hfff0_0_f&amp;c1=bi1hfff2_0_f&amp;c2=bi1hfff2_0_f&amp;c3=bi1hfff2_0_f&amp;c4=bc1dtff5_0_f&amp;t=1291847961219">Cuzillion</a>. Mais par principe un site ne devrait pas dépendre de JavaScript au point de ne pas être stylé si le <abbr>JS</abbr> n&rsquo;est pas exécuté</p>
<p>Cette technique un peu extrême trouverait cependant un intérêt si le <abbr>CSS</abbr> était parfaitement maîtrisé, auquel cas on pourrait mettre le <abbr>CSS</abbr> utile et visible inline lors de la première visite (bénéfice du <span lang="en">start render</span> rapide), charger le <abbr>CSS</abbr> via <abbr>JS</abbr>, puis marquer l&rsquo;utilisateur d&rsquo;un <span lang="en">cookie<span> signalant qu&rsquo;il a bien chargé la feuille de style pour ne lui servir que l&rsquo;<abbr>URL</abbr> du fichier (bénéfice du cache).</span></span></p>
<h3>CSS inline</h3>
<p>Une autre stratégie pour ne pas avoir à télécharger un <abbr>CSS</abbr> qui bloque le rendu est de mettre son contenu <span lang="en">inline</span>. Pour cette page en particulier, certains ont réussi à réduire le poids du <abbr>CSS</abbr> à 4Ko gzipé, alors que le <abbr>HTML</abbr> fait 8Ko gzipé. La taille totale est donc largement acceptable et cela épargne un blocage de 100ms, mais c&rsquo;est le genre de technique qu&rsquo;on n&rsquo;utilise que sur des pages très surveillées et généralement uniques (les <span lang="en">homes</span> de Yahoo! et de google par exemple).</p>
<h3>Mix Inline / Inclusion</h3>
<p>Une technique que je voulais voir en action et qui va au contraire des règles établies : mettre le minium <span lang="en">inline</span> et charger plus loin dans la source le reste des <abbr>CSS</abbr>. Ceci permet en théorie de différer le téléchargement et le <span lang="en">parsing</span> du <abbr>CSS</abbr> et de lancer au plus vite le téléchargement des images qui se trouveraient avant l&rsquo;inclusion. Le tout sans dépendre de JavaScript.</p>
<p>Mais si <abbr title="Internet Explorer">IE</abbr> commence effectivement le téléchargement des images, il attend tout de même le <abbr>CSS</abbr> avant de commencer le rendu (voir l&rsquo;effet simplifié sur <a href="http://stevesouders.com/cuzillion/?c0=hs0hfff0_0_f&amp;c1=bi1hfff2_0_f&amp;c2=bi1hfff2_0_f&amp;c3=bi1hfff2_0_f&amp;c4=bc1hfff5_0_f&amp;t=1291920593">Cuzillion</a> ou l&rsquo;effet sur <a href="http://www.webpagetest.org/video/compare.php?tests=101202_5759f68c99ab05f7b15a8a5358fff14a-r:3-c:0">la page finale</a>, créée par <a href="http://twitter.com/pixelastic">Timothée Carry-Caignon</a>). C&rsquo;est à confirmer mais le seul cas où cela pourrait marcher serait sur une page longue à calculer <span lang="en">server-side</span>, qui enverrait des bouts de <abbr>HTML</abbr> qui ne contiennent pas encore d&rsquo;appel <abbr>CSS</abbr>. Mais même là je pense que le <span lang="en">progressive rendering</span> ne serait pas satisfaisant car il y aurait un effet de <span lang="en">freeze</span> au moment où le navigateur découvrirait qu&rsquo;il y a un <abbr>CSS</abbr> à télécharger, laissant l&rsquo;utilisateur bloqué sur une page pas encore stylée.</p>
<p>Un autre essai a été <a href="http://entries.webperf-contest.com/4cd948b969dc9/index.html">tenté ici</a> par Thomas ROULET : inclusion <span lang="en">inline</span> d&rsquo;un <abbr>CSS</abbr> s&rsquo;occupant du <span lang="en">layout</span> pour que le premier rendu soit satisfaisant. Sans JavaScript, il utilise la balise <code>noscript</code> pour télécharger le <abbr>CSS</abbr>. Voici le rendu :</p>
<div id="attachment_672" class="wp-caption alignleft" style="width: 280px"><a href="http://94.23.51.58/jpvincent/blog/wp-content/uploads/2010/12/css-inline-rendu1.jpg"><img class="size-medium wp-image-672 " title="css-inline-rendu1" src="http://94.23.51.58/jpvincent/blog/wp-content/uploads/2010/12/css-inline-rendu1-300x211.jpg" alt="" width="270" height="190" /></a><p class="wp-caption-text">Rendu avec le CSS inline</p></div>
<div id="attachment_673" class="wp-caption alignright" style="width: 280px"><a href="http://94.23.51.58/jpvincent/blog/wp-content/uploads/2010/12/css-inline-rendu2.jpg"><img class="size-medium wp-image-673 " title="css-inline-rendu2" src="http://94.23.51.58/jpvincent/blog/wp-content/uploads/2010/12/css-inline-rendu2-300x211.jpg" alt="" width="270" height="190" /></a><p class="wp-caption-text">Rendu avec le CSS final</p></div>
<p>Cette technique cumule les avantages, mais pour d&rsquo;autres raison <a href="http://www.webpagetest.org/video/compare.php?tests=101202_bdfd9de7b571f2309eaf0203d1baea39-r:4-c:0">le temps</a> pendant lequel la page restait avec le <abbr>CSS</abbr> minimal était énorme</p>
<p><strong>Conclusion</strong> : ne changez rien, il faut faire télécharger le <abbr>CSS</abbr> au plus tôt. Si votre <abbr>CSS</abbr> est vraiment énorme, outre un <span lang="en">refactoring</span>, envisagez le découpage en 1 feuille légère et spécifique à une page que vous placerez <span lang="en">inline</span> et à pré-charger les <abbr>CSS</abbr> des pages suivantes.</p>
<h3>Javascript différé</h3>
<p>Certains ont utilisé des <span lang="en">lazy-loaders</span>, d&rsquo;autres ont utilisé l&rsquo;attribut <code>defer</code> (inventé par <abbr>IE</abbr>, standardisé dans <abbr>HTML5</abbr>, supporté par tous) voir <code>async</code>. Voici un petit graphe qui résume les effets de ces attributs, tiré de <a href="http://peter.sh/experiments/asynchronous-and-deferred-javascript-execution-explained/">cet article</a> :</p>
<div id="attachment_666" class="wp-caption aligncenter" style="width: 630px"><a href="http://94.23.51.58/jpvincent/blog/wp-content/uploads/2010/12/asyn-defer-js.jpg"><img class="size-full wp-image-666 " title="asyn-defer-js" src="http://94.23.51.58/jpvincent/blog/wp-content/uploads/2010/12/asyn-defer-js.jpg" alt="" width="620" height="101" /></a><p class="wp-caption-text">Comportement du navigateur avec async et defer</p></div>
<p>Dans les 2 cas cela demandait des modifications de code qui n&rsquo;ont pas été très lourdes et qui apportent un réel plus à la fluidité du chargement de la page.</p>
<h3>Lazy-loading de JS</h3>
<p>Outre le chargement différé, il était aussi possible de ne charger le <abbr>JS</abbr> qui régit l&rsquo;<span lang="en">autocomplete</span> du champs de recherche qu&rsquo;au <code>focus</code> sur ce champs. C&rsquo;est la technique dite du <span lang="en">lazy-loading</span> qui permet de ne charger les dépendances d&rsquo;une fonctionnalité que lorsqu&rsquo;on va en avoir besoin. Voir par exemple la <a href="http://fr.yahoo.com/">home de Yahoo</a>! qui est utilise à fond ce principe.</p>
<h3>Paralléliser</h3>
<p>En performances on commence toujours par là où ça va le moins vite, et là on arrive forcément à <abbr>IE6/7</abbr>. Ce navigateur n&rsquo;autorise que 2 téléchargement de <abbr>JS/CSS</abbr> en parallèle. La technique généralement pratiquée est de toute façon de n&rsquo;avoir qu&rsquo;un seul fichier de chaque type à télécharger, mais Cédric Morin a testé le regroupement puis le <span lang="en">split</span> des <abbr>JS/CSS</abbr> en 2 fichiers pour maximiser l&rsquo;utilisation de la bande passante. Résultat sur le JS :</p>
<div id="attachment_670" class="wp-caption aligncenter" style="width: 406px"><a href="http://94.23.51.58/jpvincent/blog/wp-content/uploads/2010/12/js-parallel.jpg"><img class="size-full wp-image-670" title="js-parallel" src="http://94.23.51.58/jpvincent/blog/wp-content/uploads/2010/12/js-parallel.jpg" alt="" width="396" height="32" /></a><p class="wp-caption-text">Téléchargement parallèle des 2 seuls JS de la page</p></div>
<p>Ce sont les barres bleues (le téléchargement) qui nous montrent le gain. On doit être ici à 70ms, ce qui n&rsquo;est pas énorme mais sur un site avec un <abbr>JS</abbr> plus lourd cela peut commencer à être intéressant. Et dans le cadre d&rsquo;un concours de peformance, l&rsquo;intérêt est évident <img src='http://braincracking.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Par contre, il faut bien faire attention à l&rsquo;ordre d&rsquo;exécution des scripts, mais cela peut se ranger dans des fonctions simples ou vous pouvez utiliser des librairies.</p>
<p>Concernant le <abbr>CSS</abbr> par contre, la parallélisation n&rsquo;amène rien en terme d&rsquo;accélération du rendu car les temps de téléchargement s&rsquo;additionnent (à tester sur <abbr>IE7</abbr> avec <a href="http://stevesouders.com/cuzillion/?c0=hc1hfff2_0_f&amp;c1=hc1hfff2_0_f&amp;t=1291988336258">Cuzillion</a>), mieux vaut donc rester sur un fichier unique.</p>
<h2>Techniques de lazy-loading</h2>
<p>Une des grandes techniques de la performance Web est de maîtriser parfaitement le chargement des dépendances, en les chargeant si possible au tout dernier moment, juste avant que l&rsquo;utilisateur n&rsquo;en ait besoin. C&rsquo;est en pratique difficilement applicable les yeux fermés en production car il n&rsquo;y a rien de générique, hormis <a title="jQuery lazy load" href="http://www.appelsiini.net/projects/lazyload" target="_blank">quelques</a> <a title="YUI image loader" href="http://developer.yahoo.com/yui/imageloader/" target="_blank">librairies</a> qui chargent les images non visibles au moment où l&rsquo;utilisateur scroll. Comme souvent dans les perfs, on est ici dans du spécifique pour chaque page et c&rsquo;est au développeur de bien la connaître et de savoir ce qui est important à télécharger durant la première seconde et ce qui peut être remis à plus tard.</p>
<p>Cette technique semble idéale si l&rsquo;on ne regarde que les outils de mesure automatisés puisqu&rsquo;il y a beaucoup moins d&rsquo;objets à télécharger (les outils ne scrollent pas) : le poids initial est réduit et le temps <code>onload</code> raccourci. Ca a donc remonté des concurrents en haut du tableau. Mais dans le cas de la FNAC, il était par exemple non toléré de :</p>
<ul>
<li>différer le chargement des images produit : dans un magasin, le visuel et le prix sont 2 informations de première importance. Pas de photo ou de prix, pas d&rsquo;achat. Même si la population sans javascript est de quelques %, il faut au moins que ces gens puissent voir le produit. Sur Internet, les cybermarchands espèrent en plus que des moteurs comme Google Image indexeront leurs images. Notez que pour un autre business qui accepterait de sacrifier ses utilisateurs sans JS et l&rsquo;indexation (un réseau social par exemple), cette technique très efficace aurait été acceptée</li>
<li>déclencher des téléchargements au <code>onmousemove</code> : l&rsquo;accessibilité au clavier en prend un coup</li>
</ul>
<p>Les concurrents de la catégorie meilleur poids ont choisi diverses techniques de chargement différé :</p>
<ul>
<li>placer dans une balise <code>&lt;noscript&gt;</code> le contenu de la boutique référençant les images. C&rsquo;est bien vu car les gens sans <abbr title="JavaScript">JS</abbr> et le référencement ne sont pas gênés. Le contenu est ensuite récupéré en <abbr>JS</abbr> et les images téléchargées en fonction de la zone visible. Cela a été fait avec plus ou moins de bonheur par les finalistes, mais regardez <a href="http://entries.webperf-contest.com/4cc80752a91cc/index.st.html">cette page</a> du mythique <a href="http://twitter.com/guslelapin">Cédric Morin</a> avec JavaScript désactivé pour avoir la meilleure version</li>
<li>la fnac ayant déjà fait le choix original de mettre son <span lang="en">footer</span> en <code>iframe</code>, les concurrents ont simplement retardé ou conditionné son affichage en <abbr>JS</abbr>, certains utilisant <code>&lt;noscript&gt;</code> pour la version sans <abbr>JS</abbr>.</li>
</ul>
<h2>Encodage des images</h2>
<p>La réduction du nombre de requêtes <abbr>HTTP</abbr> étant le nerf de la guerre, cela peut aller jusqu&rsquo;aux images. La technique répandue aujourd&rsquo;hui est l&rsquo;utilisation de <span lang="en">sprites</span>. Il est fortement probable qu&rsquo;elle soit remplacée demain par la technique d&rsquo;encodage des images dans le <abbr>CSS</abbr>.</p>
<h3><abbr>MHTML</abbr> et <code>data:uri</code></h3>
<p>Internet Explorer 6 et 7 supportent l&rsquo;encodage des images en <abbr>MHTML</abbr> tandis que les autres navigateurs supportent l&rsquo;encodage en <code>base64</code>. Voici <a href="http://s2.webperf-contest.com/4cd42145adb3a/c/ie.css">un exemple de <abbr>CSS</abbr></a> fait par <a href="http://www.christophelaffont.com/">Christophe Laffont</a> ne contenant que des images encodées et <a href="http://s2.webperf-contest.com/4cd42145adb3a/c/noie.css">son équivalent</a> pour les autres navigateurs. Cette technique est largement industrialisable du moment que l&rsquo;on maîtrise la fabrication de son <abbr>CSS</abbr> final avant mise en production. Plusieurs outils ont été utilisés : il existe même <a href="https://github.com/Schepp/CSS-JS-Booster">une librairie PHP</a> qui s&rsquo;occupe de concaténer les feuilles de style et de séparer les règles sans images des feuilles contenant les images encodées. Au niveau des outils :</p>
<ul>
<li>l&rsquo;encodage en <code>base64</code> peut se faire simplement <a href="http://en.wikipedia.org/wiki/Data_URI_scheme">en <abbr>PHP</abbr></a></li>
<li><a href="https://github.com/nzakas/cssembed/wiki">CSSEmbed</a> en java</li>
<li><a href="https://github.com/Schepp/CSS-JS-Booster">CSS-JS-Booster</a> en PHP</li>
<li>il existe même un <a href="http://duris.ru/">service en ligne</a> (russe)</li>
</ul>
<p>Nous attendions beaucoup du <abbr>MTHML</abbr>, et ce déploiement en situation réelle a révélé une énorme lacune. Ce graphique d&rsquo;une vue de la page en cache est révélateur :</p>
<div class="wp-caption aligncenter" style="width: 568px"><a href="http://www.webpagetest.org/results/10/12/02/5759f68c99ab05f7b15a8a5358fff14a/6_Cached_waterfall.png"><img src="http://www.webpagetest.org/results/10/12/02/5759f68c99ab05f7b15a8a5358fff14a/6_Cached_waterfall.png" alt="Page load waterfall diagram" width="558" height="112" /></a><p class="wp-caption-text">Le coût CPU du MHTML</p></div>
<p>Le <abbr>HTML</abbr> et toutes les dépendances viennent du cache, aucun téléchargement sauf le <span lang="en">tracking</span> n&rsquo;est nécessaire &#8230; mais la barre des téléchargements montre un énorme vide, expliqué par le graphe <abbr title="processeur">CPU</abbr> : il faut <a href="http://www.webpagetest.org/video/compare.php?tests=101202_5759f68c99ab05f7b15a8a5358fff14a-r:6-c:1">une pleine seconde</a> avant de rendre utilement la page !</p>
<h2>Les extrêmes</h2>
<p>Certains concurrents ont tenté des techniques extrêmes qui ont été révélatrices. Parfois disqualifiantes mais très instructives</p>
<h3>1 seule requête <abbr>HTTP</abbr></h3>
<p>Une seule requête <abbr>HTTP</abbr> au lieu des dizaines à l&rsquo;origine, c&rsquo;était théoriquement possible, et <a href="http://twitter.com/wixiweb">Arnaud Lemercier</a> l&rsquo;a osé. La page s&rsquo;affiche bien et est fonctionnelle sous <span lang="en">Firefox</span>, mais ne marche pas sous <abbr>IE7</abbr>, ce qui était disqualifiant, mais ça nous apprend plusieurs choses :</p>
<div id="attachment_618" class="wp-caption aligncenter" style="width: 620px"><a href="http://94.23.51.58/jpvincent/blog/wp-content/uploads/2010/11/1query-waterfall.png"><img class="size-full wp-image-618    " title="1query-waterfall" src="http://94.23.51.58/jpvincent/blog/wp-content/uploads/2010/11/1query-waterfall.png" alt="" width="610" height="112" /></a><p class="wp-caption-text">1 query to rule them all</p></div>
<ul>
<li>Le poids total de la page ainsi arrangée était de 500Ko. Et pourtant regardez l&rsquo;utilisation de la bande passante (graphique vert) : le <strong>navigateur fait des pauses pendant le téléchargement</strong>, mettant finalement 7s au lieu de moins d&rsquo;une seconde théorique</li>
<li>le <strong>processeur est occupé à 100%</strong> pendant 6 secondes : sans doute un mix de décompression Gzip sur un fichier qui peine à arriver, de la lecture d&rsquo;un <abbr>DOM</abbr> extrêmement lourd et d&rsquo;interprétation des images en base 64</li>
<li>les premiers pixels ne sont affichés qu&rsquo;au bout de 4,4 secondes, et on observe le même phénomène, moins gravement, sur Firefox</li>
</ul>
<p>Je cite les autres désavantages de la méthode <span lang="en">inline</span> :</p>
<ul>
<li>pas de mise en cache : les visiteurs allant sur une seconde page devront re-télécharger la plupart des éléments, ce qui est dommage pour un site comme la FNAC, mais qui n&rsquo;est pas grave pour certains sites &laquo;&nbsp;de destination&nbsp;&raquo; comme <a href="http://fr.yahoo.com/?p=us">la homepage de Yahoo</a>!</li>
<li>la technique des <code>data:uri</code> est incompatible avec <abbr>IE6-7</abbr>, il faut donc rajouter une technique équivalente appellée <abbr>MHTML</abbr>. Et donc doubler le poids des images encodées ou faire de la détection de navigateur</li>
</ul>
<p>En résumé : mettre inline <abbr>CSS</abbr>, <abbr>JS</abbr> et surtout images encodées en <code>base64</code> est extrêmement consommateur de ressources, quel que soit le navigateur au point <strong>d&rsquo;empirer la situation du <span lang="en">start render</span></strong>. Il serait intéressant de savoir si c&rsquo;est la construction d&rsquo;un <abbr>DOM</abbr> fait de 500k de texte ou si c&rsquo;est le décodage des images qui plombe à ce point les performances de rendu. Si quelqu&rsquo;un a du temps pour nous tester cela, le code source de cette page extrême est ici : <a href="http://entries.webperf-contest.com/4cd9d06f380f8/">http://entries.webperf-contest.com/4cd9d06f380f8/</a></p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/braincracking?a=jvopPO-rcvk:hSM2ErvT_Lk:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/braincracking?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=jvopPO-rcvk:hSM2ErvT_Lk:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/braincracking?i=jvopPO-rcvk:hSM2ErvT_Lk:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=jvopPO-rcvk:hSM2ErvT_Lk:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/braincracking?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=jvopPO-rcvk:hSM2ErvT_Lk:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/braincracking?i=jvopPO-rcvk:hSM2ErvT_Lk:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=jvopPO-rcvk:hSM2ErvT_Lk:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/braincracking?i=jvopPO-rcvk:hSM2ErvT_Lk:V_sGLiPBpWU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/braincracking/~4/jvopPO-rcvk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://braincracking.org/2011/01/10/concours-webperf-2010_le-chargement/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://braincracking.org/2011/01/10/concours-webperf-2010_le-chargement/</feedburner:origLink></item>
		<item>
		<title>Concours Webperf 2010 : refactoring et enseignements du concours</title>
		<link>http://feedproxy.google.com/~r/braincracking/~3/orO3AX7PVN8/</link>
		<comments>http://braincracking.org/2011/01/10/concours-webperf-2010-refactoring-et-enseignements-du-concours/#comments</comments>
		<pubDate>Mon, 10 Jan 2011 11:01:25 +0000</pubDate>
		<dc:creator>jpvincent</dc:creator>
				<category><![CDATA[Performances]]></category>
		<category><![CDATA[concours webperf 2010]]></category>
		<category><![CDATA[Perfs]]></category>

		<guid isPermaLink="false">http://braincracking.org/?p=696</guid>
		<description><![CDATA[Ce post est le dernier d&#8217;une série de 3 et est tiré de l&#8217;expérience des finalistes du concours de performance Web 2010 Les bases Maîtriser le chargement. Refactoring, enseignements. Tout développeur Web sera content de voir que les bonnes pratiques de codage aident réellement les performances de rendu, en plus de leur intérêt propre. J&#8217;ai [...]]]></description>
			<content:encoded><![CDATA[<p>Ce post est le dernier d&rsquo;une série de 3 et est tiré de l&rsquo;expérience des finalistes du concours de performance Web 2010</p>
<nav>
<ol>
<li><a href="http://braincracking.org/?p=695">Les bases</a></li>
<li><a href="http://braincracking.org/?p=617">Maîtriser le chargement</a>.</li>
<li>Refactoring, enseignements.</li>
</ol>
</nav>
<p>Tout développeur Web sera content de voir que les bonnes pratiques de codage aident réellement les performances de rendu, en plus de leur intérêt propre. J&rsquo;ai également résumé les enseignements que j&rsquo;ai tiré de ce concours</p>
<p><span id="more-696"></span></p>
<h2><abbr>HTML</abbr>, <span lang="en">markup</span> et <abbr>DOM</abbr></h2>
<p>Quand on me dit qu&rsquo;on peut accélérer le rendu d&rsquo;une page en modifiant le <abbr>HTML</abbr>, je commençais généralement à rigoler doucement : comme pour le <abbr>CSS</abbr>, je n&rsquo;ai vu aucune démonstration du phénomène<br />
Mais à bien y repenser je me souviens des grandes années du Web où j&rsquo;étais passé de <span lang="en">layouts</span> à base de <code>table</code>s imbriquées à un mix de <code>div</code>s et de règles <abbr>CSS</abbr> externalisées : non seulement le poids des pages était réduit (et à cette époque pré-<abbr>ADSL<abbr>, c&rsquo;était encore important) mais sur les machines de l&rsquo;époque on pouvait sentir la différence de rapidité d&rsquo;affichage.<br />
Et aujourd&rsquo;hui on retombe parfois sur des sites dont la maintenance n&rsquo;est pas évidente, l&rsquo;équipe sous pression et où chaque ajout au design s&rsquo;accompagne d&rsquo;une pléthore de div et de règles CSS ultra spécifiques. Même sur nos machines modernes, avec IE7 le rendu peut être ralenti sans que l&rsquo;on s&rsquo;en rende vraiment compte.</abbr></abbr></p>
<p>Force est de constater que les concurrents qui ont simplifié à la main le HTML (réduction de 30% à 50% des 1900 éléments du <abbr>DOM</abbr>) ont constaté un réel gain de vitesse de rendu. Je n&rsquo;ai aucun graphe pour le prouver (imaginez la difficulté pour mesurer cela), juste les ressentis concordants de plusieurs concurrents et un constat sur leurs pages finales.</p>
<p>L&rsquo;ordre d&rsquo;affichage a aussi son importance : sur une page statique comme ici, ça n&rsquo;était pas visible, mais un site dynamique comme la FNAC pourrait très bien envoyer son contenu par blocs en <a lang="en" href="http://fr2.php.net/flush">flushant</a> dès que possible des blocs de <abbr>HTML</abbr>. Certains comme Cédric Morin ont donc travaillé le <abbr>CSS</abbr> pour pouvoir mettre en premier dans la source les éléments importants comme la colonne centrale.</p>
<h2>Produire du bon code !</h2>
<p>Certains concurrents comme la jusqu&rsquo;au-boutiste <a href="http://twitter.com/theasta">Alexandrine Boissière</a> sont partis sur un <span lang="en">refactoring<span> complet du code, du <abbr>HTML</abbr> au <abbr>CSS</abbr> en passant par JavaScript ! Même si ça ne ressort pas forcément bien sur les graphes (par rapport aux autres finalistes), le rendu au <a href="http://www.webpagetest.org/video/compare.php?tests=101202_9729ae2f68ec0a91009a612e2e60ea7d-r:1-c:0&amp;thumbSize=200&amp;ival=100">premier affichage</a> est parfait (on voit en moins d&rsquo;une seconde le contenu principal), et la sensation de fluidité au <span lang="en">scroll</span> ou à l&rsquo;utilisation est saisissante : attendez le chargement et scrollez sur la <a href="http://entries.webperf-contest.com/base-fnac-ftw/index.html">page originale</a> et sur <a href="http://entries.webperf-contest.com/4cd5940647d03/index.html">cette page</a>. Ce n&rsquo;est pas le genre de donnée qui se calcule, sauf peut être en regardant les courbes <abbr>CPU</abbr>, mais un robot ne peut pas le calculer.</span></span></p>
<p><abbr title="Internet Explorer 7">IE7</abbr> avait visiblement du mal à afficher un arbre <abbr>DOM</abbr> aussi gros (213Ko bruts pour 2000 éléments) et avec autant d&rsquo;erreurs : plus de <a href="http://validator.w3.org/check?uri=http://entries.webperf-contest.com/base-fnac-ftw/index.html&amp;charset=(detect+automatically)&amp;doctype=Inline&amp;group=0">2300 erreurs</a> repérées par le validateur pour du <code>HTML4.01 Transitional</code>, c&rsquo;est rare. On peut donc imaginer que le parser de <abbr>IE</abbr> souffrait pour afficher la page. Certains finalistes ont :</p>
<ul>
<li>diminué de moitié le nombre de noeuds du <abbr>DOM</abbr>, ce qui influence clairement sur la fluidité finale</li>
<li>nettoyé le <abbr>HTML</abbr> des erreurs qui ont peut être une influence sur le <span lang="en">parser</span> ( <abbr>IDs</abbr> non conformes,</li>
<li>supprimé les tableaux : <abbr>IE</abbr> a toujours eu du mal avec l&rsquo;affichage de tableaux imbriqués</li>
<li>nettoyé les appels <abbr>JS</abbr> <span lang="en">inline</span></li>
<li>corrigé des erreurs de <abbr>HTML</abbr> comme des <abbr>URLs</abbr> malformées (!)</li>
<li>enlevé les paramètres de session des <abbr>URLs</abbr>, pour les rajouter en <abbr>JS</abbr> dynamiquement</li>
</ul>
<p>Au niveau <abbr>CSS</abbr> :</p>
<ul>
<li>mise en place d&rsquo;un <code>reset.css</code>, ce qui permet de supprimer beaucoup de déclarations</li>
<li>suppression des <code>filter()</code> <abbr>IE</abbr>, consommateurs de ressources. Je note au passage que cela augure du mauvais pour <abbr>CSS3</abbr> : il ne faudra pas abuser des opacités, ombrages et autres tranformations ou transitions</li>
<li>séparation des <abbr>CSS</abbr> texte des <abbr>CSS</abbr> avec images encodées</li>
<li>nettoyage des règles <abbr>CSS</abbr> inutiles sur cette page, soit 75% de la feuille. Ce nettoyage est largement discutable, car on a affaire à une feuille pour tout un site. Cependant 3/4 de règles non utilisées, ça vaut le coup à mon avis de soulager le <span lang="en">parser</span> en créant un <abbr>CSS</abbr> par type de page, généré automatiquement en concaténant une feuille de style par module par exemple.</li>
<li>utilisation de <abbr>CSS3</abbr> et de dégradation gracieuse pour les bords arrondis ou les effets de reflets. C&rsquo;est un choix que nous cautionnions, même s&rsquo;il faut bien avouer que peu d&rsquo;équipes Web arrivent à échapper au diktat du <span lang="en">pixel-perfect</span></li>
<li>utilisation de <code>:before</code> pour certains éléments répétitifs (<abbr title="Internet Explorer 6">IE6</abbr> n&rsquo;était pas à prendre en compte)</li>
<li>dégradés gérés avec un seul <abbr>PNG</abbr> transparent, la couleur étant définie en <abbr>CSS</abbr></li>
</ul>
<p>Au niveau JavaScript il y avait pas mal de ré-écriture de code à faire, même si j&rsquo;estimais personnellement cela hors-sujet du concours. Certains candidats ont pourtant gagné en fluidité grâce à cela. Je les cite en vrac :</p>
<ul>
<li>remplacement du widget d&rsquo;<span lang="en">autocomplete</span></li>
<li>moins de manipulations de <abbr>DOM</abbr></li>
<li><abbr title="+">plus</abbr> de cache sur les variables</li>
<li>optimisation des sélecteurs <span lang="en">jQuery </span></li>
<li>accès par <abbr>ID</abbr> et moins par sélecteurs (opinion personnelle : <span lang="en">jQuery</span> habitue mal les développeurs)</li>
<li>suppression du <code>document.write()</code></li>
<li>remplacer les modifications de style sur des éléments par des changements de classe</li>
<li>mutualiser les <abbr title="XMLHttpRequest, dit AJAX">XHR</abbr> qui récupéraient les infos de stock</li>
</ul>
<h2>Les enseignements du concours sur la performance Web</h2>
<ul>
<li><abbr>MHTML</abbr> est très consommateur de <abbr>CPU</abbr> et met à mal <abbr>IE7</abbr>. A utiliser avec précaution et lui préférer les sprites si nécessaire</li>
<li>la taille du <abbr>DOM</abbr> et sa complexité jouent réellement sur la vitesse et la fluidité d&rsquo;affichage</li>
<li>diviser par 10 le temps de rendu et améliorer la fluidité d&rsquo;une page comme La Fnac a maintenant un prix : une semaine à temps complet pour un développeur dans les conditions d&rsquo;une page statique. A vue de nez, pour industrialiser cela, il faut peut être décupler ce temps ?</li>
<li>les optimisations de base sont déjà très efficaces et faciles à faire, mais dans ce cas ne suffisent pas : il faut peut être envisager un refactoring</li>
<li>les bonnes pratiques du développement Web et l&rsquo;organisation de son code HTML/CSS aident réellement à garder de bonnes performances</li>
<li>les meilleurs concurrents étaient également les mieux organisés : versioning, tests automatisés des fonctionalités, processus de mise en ligne&#8230; Ils étaient également les plus clairs dans leurs notes ce qui je pense n&rsquo;est pas un hasard</li>
<li>il y a des consultants en performance qui ont participé mais les finalistes et les vainqueurs ne disent pas être des pros de la performance Web. Juste beaucoup de travail, des bonnes pratiques et de l&rsquo;auto-formation avant et pendant le concours</li>
<li>dans les techniques utilisées, il n&rsquo;y a eu que du connu, malgré la cinquantaine de cerveaux qui se sont réellement penchés sur la question. Cela signifie peut être que l&rsquo;on a fait le tour des techniques Webperf, et que le combat sera maintenant de les industrialiser et d&rsquo;en répandre l&rsquo;usage.</li>
<li>en France on n&rsquo;a pas de pétrole, mais on a de bons <abbr title="Développeur Web">Webdevs</abbr>. Les 2 tiers des participants étant français, on peut se dire qu&rsquo;il est statistiquement normal d&rsquo;avoir 3 gagnants français. Mais si on regarde la quinzaine de finalistes en haut <a href="http://webperf-contest.com/leaderboard-fr.html">du tableau</a>, il y a sur-représentation.</li>
</ul>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/braincracking?a=orO3AX7PVN8:H_roMOjp8_k:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/braincracking?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=orO3AX7PVN8:H_roMOjp8_k:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/braincracking?i=orO3AX7PVN8:H_roMOjp8_k:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=orO3AX7PVN8:H_roMOjp8_k:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/braincracking?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=orO3AX7PVN8:H_roMOjp8_k:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/braincracking?i=orO3AX7PVN8:H_roMOjp8_k:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=orO3AX7PVN8:H_roMOjp8_k:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/braincracking?i=orO3AX7PVN8:H_roMOjp8_k:V_sGLiPBpWU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/braincracking/~4/orO3AX7PVN8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://braincracking.org/2011/01/10/concours-webperf-2010-refactoring-et-enseignements-du-concours/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://braincracking.org/2011/01/10/concours-webperf-2010-refactoring-et-enseignements-du-concours/</feedburner:origLink></item>
		<item>
		<title>Tester avec fiabilité ses navigateurs</title>
		<link>http://feedproxy.google.com/~r/braincracking/~3/PEa78cwmPZ8/</link>
		<comments>http://braincracking.org/2010/11/24/tester-fiablement-ses-navigateurs/#comments</comments>
		<pubDate>Wed, 24 Nov 2010 16:46:31 +0000</pubDate>
		<dc:creator>jpvincent</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[bonnes pratiques]]></category>

		<guid isPermaLink="false">http://braincracking.org/?p=614</guid>
		<description><![CDATA[Pour une fois, ce blog ne parlera pas d&#8217;HTML5, de javascript avancé ou de performances mais de bonnes pratiques. On reste toutefois dans la modernité du développement Web, car nous allons voir pourquoi j&#8217;estime que la plupart des développeurs Web et pire, des Web agencies sont sous-équipées lorsqu&#8217;il s&#8217;agit de tester ses navigateurs. Je vous [...]]]></description>
			<content:encoded><![CDATA[<p>Pour une fois, ce blog ne parlera pas d&rsquo;HTML5, de javascript avancé ou de performances mais de <strong>bonnes pratiques</strong>. On reste toutefois dans la modernité du développement Web, car nous allons voir pourquoi j&rsquo;estime que la plupart des développeurs Web et pire, des Web agencies sont <strong>sous-équipées lorsqu&rsquo;il s&rsquo;agit de tester ses navigateurs</strong>.</p>
<p>Je vous livre même la conclusion immédiatement : <strong>vous vous devez d&rsquo;avoir des machines virtuelles</strong> pour avoir un environnement de test simplement normal et voici pourquoi.<br />
<span id="more-614"></span></p>
<h2>Je ne m&rsquo;énerve pas, j&rsquo;explique</h2>
<p>Je travaille dans des conditions outrageusement luxueuses.<br />
Comprenez par là que je bosse sur un MacBook Pro depuis 4 ans, et que j&rsquo;ai une machine virtuelle pour chaque version d&rsquo;Internet Explorer. J&rsquo;ignorais ma condition de nanti jusqu&rsquo;au jour où j&rsquo;ai travaillé avec une web agency puis discuté avec d&rsquo;autres développeurs.<br />
Ce qui comme la plupart des développeurs ne me gênait pas au début (après tout c&rsquo;est cher à mettre en place) est devenu rapidement un problème : mes prestataires ne pouvaient pas reproduire certains bugs car ils n&rsquo;avaient pas les outils nécessaires. Après une petite année à ce régime, j&rsquo;ai cumulé suffisamment de preuves pour me permettre de demander légitimement aux prochains prestas de s&rsquo;équiper avant de travailler avec nous.</p>
<h2>Arrettez les &laquo;&nbsp;compatibility mode&nbsp;&raquo;</h2>
<div id="attachment_620" class="wp-caption aligncenter" style="width: 355px"><a href="http://94.23.51.58/jpvincent/blog/wp-content/uploads/2010/11/compatibility-view.png"><img class="size-full wp-image-620" title="compatibility-view" src="http://94.23.51.58/jpvincent/blog/wp-content/uploads/2010/11/compatibility-view.png" alt="" width="345" height="89" /></a><p class="wp-caption-text">Choix du mode de compatibilité dans IE8 Debug Tool</p></div>
<p>C&rsquo;est probablement le pire moyen de tester : le mode de compatibilité d&rsquo;IE8 ou IE9 supposés exécuter le moteur de rendu d&rsquo;<abbr title="Internet Explorer 7">IE7</abbr> ou <abbr title="Internet Explorer 8">IE8</abbr>. <abbr title="Microsoft">MS</abbr> a voulu bien faire pour faciliter la vie de ses utilisateurs et leur permettre une transition en douceur de IE7 vers IE8, mais les développeurs se sont vite rendu compte que <strong>le mode de compatibilité générait des rendus différent de IE7</strong>. A tel point que Yahoo! et sa matrice de navigateurs à tester recommandent constamment de tester spécifiquement le mode de compatibilité (voir <a href="http://yuiblog.com/blog/2010/11/03/gbs-update-2010q4/">les updates</a>, dans les notes).</p>
<p><strong>Certaines techniques sont faussées</strong> : j&rsquo;ai par exemple constaté que le support des images en data:uri et base64 marchait dans IE8 en mode IE7 standard alors que IE7 ne le supporte pas. Comment faire pour valider certaines techniques émergentes (ici pour les performances) si vous n&rsquo;avez pas les bons navigateurs pour tester ?</p>
<p>La différence de comportement la plus grave que j&rsquo;ai constaté (et <a href="http://blog.dynatrace.com/2010/11/11/uncover-javascript-json-parsing-errors-with-ie-compatibility-mode/">je ne suis pas le seul</a>) vient <strong>du moteur javascript</strong> : sous <abbr title="Internet Explorer 6">IE6</abbr> et <abbr title="Internet Explorer 6">IE7</abbr>, le fait d&rsquo;oublier d&rsquo;enlever la dernière virgule (,) après une chaîne <abbr title="JavaScript Object Notation ">JSON</abbr> a toujours planté le script :</p>
<pre><code>var oData : {
	value1:"blah",
	value2:"blah", // === boom
};</code></pre>
<p>Sous <abbr title="Internet Explorer 8">IE8</abbr> comme sur tous les autres navigateurs, cette syntaxe est valide. Or si vous vérifiez avec le mode de compatibilité IE7 sous IE8, <strong>vous ne verrez pas cette erreur</strong> qui casse votre javascript et qui enlève donc des fonctionnalités majeures de votre site, simplement parce que vous n&rsquo;êtes pas dans les bonnes conditions pour tester.</p>
<h2>Les installation multiples d&rsquo;Internet Explorer</h2>
<div class="wp-caption aligncenter" style="width: 486px"><a href="http://www.my-debugbar.com/wiki/uploads/IETester/ietester-0.3.png"><img class=" " title="Screenshot IE tester" src="http://www.my-debugbar.com/wiki/uploads/IETester/ietester-0.3.png" alt="" width="476" height="275" /></a><p class="wp-caption-text">Screenshot IE tester</p></div>
<p style="text-align: left;">Internet Explorer est à ce point implanté dans son OS qu&rsquo;il est en théorie impossible d&rsquo;installer plusieurs versions d&rsquo;Internet Explorer (ce qui leur avait même valu des <a href="http://en.wikipedia.org/wiki/United_States_v._Microsoft">problèmes avec la justice</a>). Mais plusieurs softs ont pallié à cette situation et permettent <strong>d&rsquo;exécuter plusieurs versions d&rsquo;IE</strong> comme <a href="http://www.my-debugbar.com/wiki/IETester/HomePage">IETester</a>, <a href="http://utilu.com/IECollection/">IECollection</a> ou <a href="http://tredosoft.com/Multiple_IE">Multiple IE</a>. Le problème, c&rsquo;est que ces différentes instances d&rsquo;IE continuent de partager certaines DLLs et autres appels système. Ca n&rsquo;a l&rsquo;air de rien, mais concrètement pour le développeur Web ça l&rsquo;empêche de voir certaines choses :</p>
<h3>Plugins</h3>
<p>Les interaction avec des plugins populaires comme Flash ou Java sont problématiques :</p>
<ul>
<li>J&rsquo;ai déjà vu Flash planter sans que IE dans un IETester ne s&rsquo;en aperçoive, le fallback que nous implémentions en Flash (la sélection multiple de fichiers pour un uploader) était essentiel, mais le développement était pénible : on s&rsquo;est rendu compte au bout d&rsquo;un moment que <strong>Flash ne répondait plus ou mal</strong>, et qu&rsquo;il fallait tuer le processus Flash pour que cela remarche. Avec un <strong>IE natif, pas de problèmes</strong> : lorsque Flash plante, il se relance correctement, ce qui accélérait le développement</li>
<li>l&rsquo;interaction avec une applet java (toujours pour un uploader, en drop de fichiers cette fois) était tout simplement <strong>impossible à tester avec plusieurs IE</strong> dans le même IETester. Une machine virtuelle, c&rsquo;est déjà lourd à lancer, alors imaginez 3 applets en parallèle qui essayent de s&rsquo;afficher sur la même zone de l&rsquo;écran. Les fichiers n&rsquo;étaient pas réceptionnés dans la bonne instance d&rsquo;IE &#8230;</li>
</ul>
<h3>Fonts et couleurs</h3>
<p>Pour le rendu des fonts il vous faudra typiquement vérifier votre site sous un Safari sur Mac et sur un IE6 sous XP : le <strong>Safari Mac rend les polices exactement comme votre graphiste l&rsquo;a prévu</strong> sur sa belle maquette Photoshop. C&rsquo;est la vision qu&rsquo;il a du site, et c&rsquo;est surement celle que les décideurs ont du site &#8230;<br />
Le couple terrible IE6-XP qui est encore là pour longtemps est lui à <strong>l&rsquo;extrémité opposée du spectre des rendus</strong>, et correspond au pire de ce que verront vos visiteurs. Les versions supérieures de IE et des navigateurs ne font qu&rsquo;améliorer le rendu sans jamais totalement atteindre la perfection du couple Safari / OSX.</p>
<div id="attachment_634" class="wp-caption aligncenter" style="width: 552px"><a href="http://94.23.51.58/jpvincent/blog/wp-content/uploads/2010/11/rendu_police.png"><img class="size-full wp-image-634" title="rendu_police-mini" src="http://94.23.51.58/jpvincent/blog/wp-content/uploads/2010/11/rendu_police-mini.png" alt="" width="542" height="67" /></a><p class="wp-caption-text">Au moins 4 rendus par police</p></div>
<p>J&rsquo;ajoute que selon la taille de police, l&rsquo;activation ou pas de l&rsquo;option lissage, le type de police et les caractères utilisés, certains mots peuvent devenir illisibles ou du moins pénibles à lire sur les Windows. Lorsque vous décidez de l&rsquo;utilisation d&rsquo;une police, il vous faudra d&rsquo;abord <strong>vérifier son rendu final sur au moins XP, Vista ou Seven, et enfin MacOS</strong>. Soit vous maintenez 3 machines physiques avec 1 OS sur chacun, soit vous utilisez les machines virtuelles (ou plus pénible : des machines en dual boot).</p>
<p>Le rendu des couleurs : j&rsquo;avoue ne pas très bien savoir comment faire ici. Mac et les différents Windows rendent les couleurs différemment, discutez en 2 minutes avec un graphiste, ça lui laissera le loisir de vous montrer qu&rsquo;il en sait plus que vous. Hors avec les machines virtuelles, on affiche un Windows sur un Mac, je n&rsquo;ai aucune idée de ce que cela donne réellement. Pour en rajouter un peu, je n&rsquo;obtiens pas les mêmes couleurs selon que je suis sur l&rsquo;écran du macbook ou sur le 2nd écran &#8230; Devant mon incapacité à vous expliquer comment tout cela marche, je ne peux que citer une des bonnes pratiques généralement accolée à l&rsquo;accessibilité : <strong>inutile de jouer avec des nuances de couleurs, préférez de forts contrastes</strong>.</p>
<h3>Etre à jour</h3>
<p>Microsoft patche régulièrement ses OS ainsi que ses IE. Rarement mais sûrement certaines choses peuvent <strong>s&rsquo;arrêter de fonctionner suite à ces patchs</strong>. Exemple concret : dans les IEs on pouvait récupérer le chemin local d&rsquo;un fichier sélectionné par un <code>input type=file</code>. Ceci permettait d&rsquo;afficher une miniature d&rsquo;une image avant upload, fonctionnalité d&rsquo;ailleurs à nouveau permise par HTML5. En 2009 un patch est passé qui a fait disparaître cette possibilité, après 10 ans de bons et loyaux services (voir <a href="http://braincracking.org/2009/11/27/cest-comme-ca-quon-fixe-les-bugs-chez-ms/">les screenshots</a> que j&rsquo;avais fait).</p>
<p>Les packs d&rsquo;IE ne permettent pas de rester à jour, ou alors vous dépendez de leur bon vouloir. Avoir une machine virtuelle permet d&rsquo;utiliser le mécanisme d&rsquo;auto-update de MS.</p>
<h3>Autres fonctionnalités cassées</h3>
<p>Il y a d&rsquo;autres bugs connus sur Multiple IE ou IETester :</p>
<ul>
<li>les champs texte sur &laquo;&nbsp;Multiple IE&nbsp;&raquo; ne fonctionnent plus
<li>les popups et leur interaction avec la page d&rsquo;appel est cassée
<li>les filtres CSS ne marche pas
<li>la fonctionnalité d&rsquo;impression ne marche pas
</ul>
<h2>Dégradation gracieuse et Fallbacks</h2>
<h3>Les anciens et les futurs navigateurs</h3>
<p>Outre Internet Explorer, certains versions de Firefox valent encore la peine d&rsquo;être testés avec plusieurs versions. Ca a été le cas pendant longtemps pour <abbr title="Firefox 3.0">FF3</abbr>, c&rsquo;est encore peut être le cas sur vos sites pour <abbr title="Firefox 3">FF3.5</abbr> et à l&rsquo;heure d&rsquo;écrire ce post, c&rsquo;est certainement vrai pour FF3.6, alors que l&rsquo;on est passé à la 4.0.</p>
<p>Les bugfixs passés dans ces releases impactent rarement le travail des webdevs (mais ça arrive) mais il y a surtout eu des <strong>ajouts de fonctionnalité majeures</strong> (rangées sous l&rsquo;ombrelle HTML5) ou l&rsquo;ajout de supports CSS3 : il faut que vous testiez au moins une fois pendant le développement <strong>comment se comporte votre fallback ou votre graceful degradation sur ces anciennes versions</strong>.</p>
<p>Il n&rsquo;est peut être pas utile de conserver des versions de Chrome et Opéra, l&rsquo;un car il force l&rsquo;auto-update, l&rsquo;autre parce qu&rsquo;il est rare, mais c&rsquo;est à vous de juger.</p>
<p><img class="alignleft size-full wp-image-641" title="firefox4" src="http://94.23.51.58/jpvincent/blog/wp-content/uploads/2010/11/firefox4.png" alt="" width="274" height="134" />Par contre il est vital d&rsquo;avoir <strong>les versions de développement de IE (la 10 preview) et Firefox (Minefield)</strong> pour tester régulièrement votre site avec : faites corriger les bugs <a title="exemple de bug que j'ai ouvert" href="https://connect.microsoft.com/IE/feedback/details/549601/ie9-preview-fails-to-manage-script-type-text-html">par Microsoft</a> ou <a title="exemple de bug que j'ai ouvert" href="https://bugzilla.mozilla.org/show_bug.cgi?id=610378">par Mozilla</a> avant que vos utilisateurs ne tombent dessus et vous fasse changer votre code !</p>
<p>Il n&rsquo;est peut être pas nécessaire d&rsquo;avoir une machine virtuelle dédiée à une version passées et futures des navigateurs hors IE, car il me semble que différentes versions de FF savent cohabiter ensembles et que les beta/preview d&rsquo;IE savent également s&rsquo;installer sans conséquences. Mais il vaut peut être mieux <strong>jouer la prudence</strong> là dessus : ce sont des versions beta et avec les nouvelles fonctionnalités type accélération matérielle, les navigateurs s&rsquo;intègrent de plus en plus au système, il me semble donc évident que <strong>toute nouvelle installation met en péril l&rsquo;intégrité des autres versions du même navigateur</strong>.<br />
Et une fois que le mal est fait, difficile de revenir en arrière, tandis que sur une machine virtuelle vous pouvez isoler le problème, et vous pouvez même <strong>revenir en arrière grâce aux fonctionalités de snapshot</strong> à exécuter avant toute installation hasardeuse.</p>
<h3>Plugins et addons</h3>
<p>Votre site dépend parfois de Flash ou Java ? Il affiche des publicités ?<img class="aligncenter size-full wp-image-644" title="no-flash" src="http://94.23.51.58/jpvincent/blog/wp-content/uploads/2010/11/no-flash.jpg" alt="" width="450" height="371" /> Il vous faut au moins une machine où Flash et Java ne sont pas installés, afin de <strong>tester de manière réaliste votre contenu alternatif ou le fallback de votre fonctionnalité</strong>. On ne développe pas ce qu&rsquo;on ne voit pas.</p>
<p>Concernant Flash, et c&rsquo;est valable avec Java : il existe des différences entre Flash 9 (encore répandu) et Flash 10.x. Les flasheurs développent et testent toujours avec la dernière version : ayez donc une machine avec une ancienne installation de Flash pour <strong>vérifier rapidement que le Flash qu&rsquo;on vous livre marche pour tout le monde</strong>.</p>
<p>Votre Firefox est peut être comme le mien : c&rsquo;est devenu un navigateur de développement sur lequel est installé une dizaine de plugins dont le gourmand firebug. Après quelques heures de développement mon Firefox est à la limite du praticable sur certaines pages chargées. Un tour régulier sur un Firefox sans aucun plugin dans une machine virtuelle me permet <strong>de vérifier (et non pas de supposer) si c&rsquo;est un plugin ou mon code qui fait ramer le navigateur</strong>.</p>
<h2><strong>Quelles contraintes ?</strong></h2>
<p>Vous êtes probablement d&rsquo;accord avec le principe d&rsquo;être dans de bonnes conditions pour tester, mais vous avez peur que cela demande <strong>du budget et de la ressource machine</strong> ? C&rsquo;est le cas, mais rien d&rsquo;insurmontable. Concernant votre machine de développement d&rsquo;abord :</p>
<ul>
<li><strong>Mac OS</strong> : il faudra le tester de toute façon, ne serait ce que pour tester ce que voient<strong> les graphistes et les journalistes</strong>&#8230; Pendant longtemps il n&rsquo;y a pas eu de machine virtuelle capable de le faire tourner mais <a title="Guide d'installation VMWare" href="http://www.redmondpie.com/how-to-install-os-x-snow-leopard-in-vmware-windows-7-9140301/">il semblerait</a> que cela soit aujourd&rsquo;hui possible, donc si vous voulez rester sous Windows ou Linux, c&rsquo;est peut être jouable, à vos risques et périls. Pour ma part et depuis 4 ans, j&rsquo;ai convaincu mes employeurs de payer 50% plus cher mon matériel pour être dans des conditions de test réalistes. Pour les managers qui doivent justifier ce budget : outre la qualité, un développeur sous mac est un développeur qui restera plus longtemps chez vous <img src='http://braincracking.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
<li><strong>4GO de RAM</strong> : pendant le développement, il faut tourner avec au moins un IE6 (ou 7) sous XP en permanence ouvert en plus l&rsquo;environnement de développement normal (Firefox, éditeurs, divers logiciels &#8230;). Avec <strong>2Go, c&rsquo;est parfois pénible</strong>, du coup certains développeurs ferment à jamais la machine. 4Go, c&rsquo;est mieux, et ça permet de supporter ces jours pénibles, généralement en début et en fin de projet, où vous allez lancer successivement toutes vos machines virtuelles pour valider des choix techniques ou le développement lui même.</li>
<li><strong>un disque rapide</strong> : 2 OS qui cohabitent, ça fait énormément d&rsquo;appels au disque dur, surtout que vous allouerez peu de RAM à Windows (512Mo max en général), et ce dernier utilisera la mémoire virtuelle (le disque donc). Si vous n&rsquo;avez que 2Go de RAM et un disque de portable à 5400 tr/mn, la situation sera intenable. Essayez d&rsquo;upgrader à 7200 (la différence est flagrante), voir de le remplacer par un SSD, technologie qui commence à être abordable.
</ul>
<p>Concernant le software :</p>
<ul>
<li>XP et Seven : il vous faut au moins ces 2 OS pour installer de IE6 à IE9. Concernant les licenses, chez Yahoo! nous utilisions des licences dites corporate (valables pour des milliers de postes), donc pas de problème. En PME, la pratique généralement admise est d&rsquo;acheter la licence, d&rsquo;installer &#8230; puis de cloner l&rsquo;image de la machine autant de fois qu&rsquo;il y a d&rsquo;environnement et de développeur. Honnêtement <strong>je ne sais pas si c&rsquo;est prévu par la licence</strong>. Si vous émulez à partir de Seven avec Virtual PC, Microsoft vous offre <a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=21eabb90-958f-4b64-b5f1-73d0a413c8ef&amp;displaylang=en">des images d&rsquo;installation</a> (limitées dans le temps) parfaites pour les webdevs.</li>
<li>Une machine virtuelle Mac :
<ul>
<li>payant : j&rsquo;utilise <a href="http://www.parallels.com/fr/products/desktop/">Parallels Desktop</a> qui me satisfait pleinement mais qui a la réputation d&rsquo;être gourmand en ressources. J&rsquo;ai entendu du bien de <a href="http://www.vmware.com/products/fusion/">VMWare</a>. Dans tous les cas comptez <strong>moins de 100 euros</strong>.</li>
<li>gratuit : <a href="http://www.virtualbox.org/">VirtualBox</a> est le leader de l&rsquo;open source, mais n&rsquo;était pas sorti lorsque j&rsquo;ai commencé à utiliser Parallels il y a 4 ans, je ne peux donc pas en parler. <strong>Si vous êtes sur Windows Seven, vous pouvez utiliser <a href="http://www.microsoft.com/windows/virtual-pc/default.aspx">Virtual PC</a></strong>.</li>
</ul>
</li>
</ul>
<p>Les machines virtuelles vous fournissent généralement des images pré-installées. Mais elles ne sont jamais en français, et bien sur ne dispensent pas de fournir une clé Windows valide. Veillez aussi à ce que les images d&rsquo;XP fournies contiennent bien IE6 :  on ne peut pas désinstaller IE7 pour installer IE6.</p>
<h2>La matrice de tests</h2>
<p>Je vous conseille de suivre <a href="http://developer.yahoo.com/yui/articles/gbs/">la matrice de Yahoo</a>!, mise à jour 2 à 3 fois par an. Voici en tout cas le contenu de mes machines après plusieurs années de pratique :</p>
<div id="attachment_639" class="wp-caption aligncenter" style="width: 574px"><a href="http://94.23.51.58/jpvincent/blog/wp-content/uploads/2010/11/machines.gif"><img class="size-full wp-image-639" title="machines" src="http://94.23.51.58/jpvincent/blog/wp-content/uploads/2010/11/machines.gif" alt="" width="564" height="407" /></a><p class="wp-caption-text">Liste des configurations dans Parallels</p></div>
<p>Vista et FF2-3 ne sont peut être plus utiles à posséder, mais sinon toutes ces combinaisons tiendraient en 5 machines. Cela donne accès à :</p>
<ul>
<li>pas de flash/java, flash 9 et un Flash à jour partout ailleurs</li>
<li>IE 6, 7 et 8 sur XP, IE9 sur Seven</li>
<li>FF3.6 et FF4 (qui n&rsquo;apparaît pas)</li>
<li>IE10 preview à jour, un FF Minefield pour vérifier des bugfix à l&rsquo;occasion</li>
<li>Ces machines comportent presque toutes un Chrome et un Opéra à jour, en plus du Chrome / Opéra / Safari de mon Mac. Oui il y a parfois des différences pas uniquement visuelles entre une version Mac et Windows d&rsquo;un même navigateur.</li>
</ul>
<p>Cela fait beaucoup de combinaisons et il en manque encore : par exemple si je dois un jour tester le site sur IE6 sans Flash, je n&rsquo;ai pas de machine toute prête. Qu&rsquo;à cela ne tienne, il me suffit de cloner ou de faire un snapshot de ma machine IE6 puis de desinstaller Flash pour vérifier mon bug.</p>
<h2 title="Mis à jour le 1er janvier 2011">Les alternatives</h2>
<h3>Service en ligne</h3>
<p>Des services comme <a href="http://browsershots.org/">browsershots.org</a> ou <a href="https://browserlab.adobe.com/fr-fr/features.html#PreviewAnything">browserlab</a> permettent d&rsquo;obtenir rapidement un screenshot d&rsquo;une page vue par beaucoup de couples OS/navigateurs différents. Le désavantage évident, et dans mon cas bloqueur, est que votre page doit être sur une <abbr>URL</abbr> publique et que vous ne pouvez pas interagir avec la page. Peu d&rsquo;équipe développent directement en ligne, préférant des <abbr>URL</abbr>s internes, et il est difficile de se passer de tester des interaction (<code>:hover</code>, formulaires, application Web &#8230;)</p>
<h3>Machines physiques</h3>
<p>Les machines physiques sont encore plus réalistes que les machines virtuelles, en théorie vous y gagnerez donc en qualité de test. Le point négatif que j&rsquo;ai expérimenté ne vient pas de l&rsquo;outil mais de la nature humaine : accessibles physiquement ou depuis un <a href="http://www.realvnc.com/vnc/index.html">VNC</a>, c&rsquo;est une solution peu pratique que les développeurs finissent par ne plus utiliser, préférant coder à l&rsquo;aveugle plutôt que de se déplacer physiquement ou subir des lags réseau&#8230; Oui les développeurs sont comme ça, d&rsquo;où l&rsquo;intérêt d&rsquo;investir dans du matériel <img src='http://braincracking.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>J&rsquo;ajoute que les machines virtuelles permettent de faire des <span lang="en">snapshots</span>, ce qui permet de gagner en souplesse en installant sans remords des programmes pour tester certaines conditions extrêmes (IE toolbars, mises à jour de Flash, <span lang="en">Silverlight</span> et Java, reproduire un bogue avec un antivirus agressif &#8230;). Maintenir un parc de machines physiques qui permet d&rsquo;avoir autant de souplesse prendrait beaucoup de temps</p>
<h3>Linux, windows comme OS principal</h3>
<p>Par conviction ou par économie, vous pouvez préférer développer sur autre chose que Mac OS. Sur ces 2 familles d&rsquo;OS vous pouvez tout à fait créer des machines virtuelles, mais il vous reste cependant le problème de l&rsquo;émulation du Mac (je maintiens qu&rsquo;il faut le tester quoi qu&rsquo;il en coûte) : à priori la seule solution viable est d&rsquo;avoir une machine physique Mac constamment à jour que l&rsquo;équipe pourra utiliser. Mais d&rsquo;expérience cette machine finira par être sous utilisée, et donc les tests de compatibilité seront moins assurés.</p>
<h2>Conclusion</h2>
<ul>
<li>Si vous vous considérez comme un professionnel du Web, vous vous devez d&rsquo;investir dans un environnement de test fiable</li>
<li>Il y a de vraies différences de comportement et de rendu entre un IE natif et des packs d&rsquo;IE, et entre OS</li>
<li>Il y a un gros nombre de combinaisons possibles (4 OS, 5 navigateurs, plusieurs sous-versions, Flash &#8230;) et les différences iront en s&rsquo;accentuant (nouveaux navigateurs, adaptation à chaque OS &#8230;)</li>
<li>La seule solution fiable et souple est d&rsquo;avoir plusieurs machines virtuelles</li>
<li>Il vous faut une machine Mac OS physique pour tester cet OS (une machine partagée ou une par développeur)</li>
</ul>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/braincracking?a=PEa78cwmPZ8:Dn6K9YG_rgI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/braincracking?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=PEa78cwmPZ8:Dn6K9YG_rgI:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/braincracking?i=PEa78cwmPZ8:Dn6K9YG_rgI:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=PEa78cwmPZ8:Dn6K9YG_rgI:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/braincracking?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=PEa78cwmPZ8:Dn6K9YG_rgI:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/braincracking?i=PEa78cwmPZ8:Dn6K9YG_rgI:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=PEa78cwmPZ8:Dn6K9YG_rgI:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/braincracking?i=PEa78cwmPZ8:Dn6K9YG_rgI:V_sGLiPBpWU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/braincracking/~4/PEa78cwmPZ8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://braincracking.org/2010/11/24/tester-fiablement-ses-navigateurs/feed/</wfw:commentRss>
		<slash:comments>32</slash:comments>
		<feedburner:origLink>http://braincracking.org/2010/11/24/tester-fiablement-ses-navigateurs/</feedburner:origLink></item>
		<item>
		<title>Concours de performances Web : à vous de jouer</title>
		<link>http://feedproxy.google.com/~r/braincracking/~3/BhTV-sTm46U/</link>
		<comments>http://braincracking.org/2010/10/27/concours-de-performances-web-a-vous-de-jouer/#comments</comments>
		<pubDate>Wed, 27 Oct 2010 07:00:39 +0000</pubDate>
		<dc:creator>jpvincent</dc:creator>
				<category><![CDATA[Performances]]></category>
		<category><![CDATA[concours]]></category>
		<category><![CDATA[Perfs]]></category>

		<guid isPermaLink="false">http://braincracking.org/?p=607</guid>
		<description><![CDATA[Hier s&#8217;est ouvert le premier (ok, le second dans l&#8217;idée) concours international de Performances Web, il durera jusqu&#8217;au 30 novembre. EDIT : le concours 2010 est maintenant fini, vous pouvez voir les gagnants ici et l&#8217;analyse des techniques employés là Comment ça marche ? Le principe est simple : tous les développeurs doivent optimiser la [...]]]></description>
			<content:encoded><![CDATA[<p>Hier s&rsquo;est ouvert le premier (ok, <a href="http://www.fastwebrace.com/">le second</a> dans l&rsquo;idée) concours international de Performances Web, il durera jusqu&rsquo;au 30 novembre.<br />
<span id="more-607"></span><br />
EDIT : le concours 2010 est maintenant fini, vous pouvez voir les gagnants <a href="http://webperf-contest.com/">ici</a> et <a href="http://braincracking.org/?p=717">l&rsquo;analyse des techniques employés là</a></p>
<h2>Comment ça marche ?</h2>
<p>Le principe est simple : tous les développeurs doivent <strong>optimiser la même page</strong>, page prêtée par <a href="http://www.fnac.com/enfants.asp">La Fnac</a>, et mise à disposition sous forme de fichiers statiques que vous pourrez modifier à volonté. On parle donc bien d&rsquo;un concours de performances frontales, puisque le code backend ne peut pas influer sur le temps d&rsquo;affichage de la page. Ce qui tombe bien car c&rsquo;est là où passe 90% du temps d&rsquo;affichage : sur cette <strong>page très représentative</strong> des sites Web d&rsquo;aujourd&rsquo;hui, 1 seconde suffit à générer le HTML, les fichiers statiques sont servis en 50ms chacun, ce qui correspond à des performances honorables côté backend. <strong>Mais le site n&rsquo;est pas utilisable avant plusieurs secondes </strong>(voir <a href="http://www.webpagetest.org/result/101026_9ANH/">ce graphique</a>).  <a href="http://webperf-contest.com/register-fr.html">Inscrivez vous</a> donc et visez une des 3 catégories (ou toutes, ce qui est théoriquement possible) :</p>
<ul>
<li>meilleur score YOTTA (sponsor principal fournissant des outils de monitoring de performances). Le score YOTTA est, je cite : <cite lang="en">&laquo;&nbsp;an overall performance assessment that takes into account page load time, global reachability, yslow and complexity&nbsp;&raquo;</cite>. Récompense : <strong>un iPad</strong></li>
<li>meilleur temps d&rsquo;affichage, calculé par l&rsquo;indispensable <a href="http://www.webpagetest.org">webpagetest.org</a> depuis un IE7 à Paris. Le start render actuel est à 2.5s et n&rsquo;est pas très utile (voir <a href="http://www.webpagetest.org/results/10/10/26/9ANH/1_screen_render.jpg">ce screenshot</a>), d&rsquo;autant qu&rsquo;il est suivi par un freeze du navigateur perceptible à la souris nue, et visible facilement sur <a href="http://www.webpagetest.org/waterfall.png?type=connection&amp;width=930&amp;test=101026_9ANH&amp;run=1&amp;cached=1">ce graphique</a> où l&rsquo;on voit le CPU plafonner à 100% pendant plusieurs secondes. Le temps onload total est de plus de 7 secondes, je pense que le diviser en 2 avec des fichiers statiques et un peu de malice est largement jouable. Récompense : un <strong>iPod touch</strong></li>
<li>plus petit nombre de requêtes HTTP et poids total, calculés en additionnant première et seconde impression de la page. La difficulté dans cette catégorie est que les techniques permettant l&rsquo;un et l&rsquo;autre sont parfois antinomiques. Récompense : <strong>des livres dédicacés</strong> par <a href="http://phpied.com/">Stoyan Stefanov</a></li>
</ul>
<p>Une fois inscrit, vous recevez un espace FTP et un ZIP contenant les fichiers statiques.</p>
<h1>J&rsquo;ai une chance ?</h1>
<p>L&rsquo;idée du concours est bien sur d&rsquo;apprendre en s&rsquo;amusant, avec la concurrence comme aiguillon. En passant du temps sur cette page de la FNAC, vous allez pouvoir mettre les mains dans le cambouis, et on sait bien qu&rsquo;en terme de développement en général, et d&rsquo;optimisation en particulier, c&rsquo;est la meilleure école. A mon sens la connaissance basique des performances Web fait maintenant partie intégrante de l&rsquo;arsenal d&rsquo;un développeur Web moderne, au même titre que le respect des balises HTML ou du passage des layouts en tableau au tout-CSS il y a plusieurs années.  Accessoirement, c&rsquo;est l&rsquo;un des premiers concours avec ce thème et la discipline commence à peine à être maîtrisée. Pour preuve, il doit y avoir moins de 10 professionnels vivant uniquement du consulting sur les performances Web dans le monde, et un seul en France (<a href="http://zeroload.net/">Zerolad</a>, par Vincent Voyer, organisateur principal). Nous sommes donc tous plus ou moins amateurs, peu nombreux et vous avez dès lors de vraies chances de gagner.</p>
<h1>Quelques conseils</h1>
<p>Etant donné que je suis juge, je vais tenter de rester impartial pour ne pas favoriser les français ou mes lecteurs. Cependant je vais vous faciliter la tâche en rappelant ces quelques ressources qui vous donneront une idée de par où commencer. Ces ressources sont publiques et vous serviront même en dehors de ce concours.</p>
<ul>
<li>la liste de référence toujours valable <a href="http://developer.yahoo.com/performance/rules.html">faite par Yahoo</a>! : Dans le cadre de ce concours, il est clair qu&rsquo;il vous faut au moins assurer sur la majorité de ces conseils. C&rsquo;est de toute façon une connaissance et des techniques qui vous serviront sur tous les sites.</li>
<li>l&rsquo;autre liste de référence, <a href="http://code.google.com/intl/fr/speed/page-speed/docs/rules_intro.html">faite par Google</a>. Les points se recoupent aussi en général je me contente de citer la liste de Yahoo!. Mais pour ce concours, vous voudrez certainement optimiser plus avant et certains points innovateurs de Google devraient vous aider à gratter des dixièmes de secondes ou quelques kilos</li>
<li>les archives d&rsquo;<a href="http://performance.survol.fr/">Eric Daspet</a> (co-organisateur et juge), qui bloguait en français à l&rsquo;époque où toutes les règles de performances commençaient à sortir</li>
<li>mes propres archives des <abbr title="Revue de Presse Web">RPW</abbr> taguées &laquo;&nbsp;<a href="http://braincracking.org/tag/perfs/">Perfs</a>&nbsp;&raquo; qui couvrent elles l&rsquo;année écoulée et qui contiennent des conseils généraux et aussi quelques techniques extrêmes difficile à sortir en production mais qu&rsquo;il serait intelligent de déployer dans un concours de performances Web <img src='http://braincracking.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
</ul>
<p>Côté outils, pour vous éviter beaucoup de choses fastidieuses, surtout les premières heures :</p>
<ul>
<li>les classiques <a href="http://developer.yahoo.com/yslow/">ySlow</a> et <a href="http://code.google.com/intl/fr/speed/page-speed/download.html">pageSpeed</a>, pour repérer facilement les problèmes basiques, sur Firefox. Le score ySlow fait d&rsquo;ailleurs partie du score YOTTA</li>
<li>le complexe mais très utile <a href="http://ajax.dynatrace.com/pages/download/download.aspx">dynatrace AJAX</a>, pour Internet Explorer. Il permet notamment de comprendre comment IE affiche une page, et peut vous aider à repérer d&rsquo;autres problèmes invisibles de firebug</li>
<li>le méconnu <a href="http://sourceforge.net/projects/pagetest/files/">AOL page Test</a> pour IE, qui est en fait le logiciel utilisé par WebPageTest.org . 3 avantages :
<ul>
<li>Vous verrez votre page comme la verront les juges <img src='http://braincracking.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
<li>Vous ne dépendez pas de Webpagetest.org qui sera forcément saturé de demandes des autres concurrents</li>
<li>Vous ne révélerez pas votre URL secrète par erreur aux autres concurrents en passant par WebPageTest.org . Il suffit d&rsquo;oublier de cocher la case &laquo;&nbsp;private&nbsp;&raquo; une fois &#8230;</li>
</ul>
</li>
<li>IE7 ! c&rsquo;est notre étalon, il ne faut donc pas se baser sur des navigateurs plus récents comme IE8 et Firefox. Vous devriez y installer AOL page Test pour voir la page telle que Webpagetest.org la testera. Faîtes attention aux packs d&rsquo;IE : ils dépannent dans la majorité des cas, mais j&rsquo;ai déjà noté des différences de comportement (filtres CSS, interaction avec plugins et addons &#8230;) et je ne sais pas si cela influe sur la manière d&rsquo;afficher une page (nombre de requêtes parallèles par exemple). Utilisez une machine virtuelle pour chaque IE reste un bon conseil.</li>
</ul>
<p>Et enfin des discussions :</p>
<ul>
<li>le <a href="http://groups.google.fr/group/performance-web">groupe de discussion performances Web</a> français lancé cet été à la suite de la première soirée Webperfs où vous devriez trouver tous ceux qui ressemblent à un expert des performances Web</li>
<li>un forum ouvert récemment pour l&rsquo;occasion sur <a href="http://www.developpez.com/redirect/183">developpez.com</a>, et qui restera sûrement après le concours. Nous surveillons ce forum pour répondre à vos questions si vous sentez que vous tentez des optimisations un peu trop extrêmes et que vous n&rsquo;êtes pas surs que nous les accepterons au final</li>
<li>et bien sur le twitter officiel du concours : @<a href="http://twitter.com/webperf_contest">webperf_contest</a> qui vous permet de dialoguer directement avec nous</li>
</ul>
<p>Un dernier conseil pour ce concours : remplissez bien votre Gist de toutes les modifications que vous faîtes. Nous nous doutons que les finalistes arriveront dans la même plage de 50-100ms et il serait injuste que les aléas du réseau choisissent un gagnant. Pour les départager, nous allons tout simplement lire les techniques que vous aurez appliquées et voter au plus méritant (originalité, facilité de mise en oeuvre &#8230;)  Voilà, <a href="http://webperf-contest.com/register-fr.html">inscrivez vous</a>, téléchargez et jouez avec la page. C&rsquo;est le moment d&rsquo;apprendre et peut être même de gagner des bouquins ou un peu d&rsquo;électronique <img src='http://braincracking.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/braincracking?a=BhTV-sTm46U:yoACBzT7avw:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/braincracking?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=BhTV-sTm46U:yoACBzT7avw:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/braincracking?i=BhTV-sTm46U:yoACBzT7avw:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=BhTV-sTm46U:yoACBzT7avw:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/braincracking?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=BhTV-sTm46U:yoACBzT7avw:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/braincracking?i=BhTV-sTm46U:yoACBzT7avw:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=BhTV-sTm46U:yoACBzT7avw:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/braincracking?i=BhTV-sTm46U:yoACBzT7avw:V_sGLiPBpWU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/braincracking/~4/BhTV-sTm46U" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://braincracking.org/2010/10/27/concours-de-performances-web-a-vous-de-jouer/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://braincracking.org/2010/10/27/concours-de-performances-web-a-vous-de-jouer/</feedburner:origLink></item>
		<item>
		<title>Conférence Paris Web : HTML5 c’est maintenant (IE6 inclus)</title>
		<link>http://feedproxy.google.com/~r/braincracking/~3/-NEHJi_6uwM/</link>
		<comments>http://braincracking.org/2010/10/15/conference-paris-web-html5-cest-maintenant-ie6-inclus/#comments</comments>
		<pubDate>Fri, 15 Oct 2010 08:00:56 +0000</pubDate>
		<dc:creator>jpvincent</dc:creator>
				<category><![CDATA[HTML5]]></category>

		<guid isPermaLink="false">http://braincracking.org/?p=597</guid>
		<description><![CDATA[J&#8217;ai eu l&#8217;honneur de présenter à Paris Web 2010 un thème que vous retrouvez souvent sur ce blog : les applications Web. Le titre exact était &#171;&#160;HTML5 c&#8217;est maintenant (IE6 inclus)&#160;&#187;, ce qui est un clin d&#8217;oeil au grand écart que les développeurs Web font constamment entre les anciens navigateurs et les nouvelles fonctionnalités. Il [...]]]></description>
			<content:encoded><![CDATA[<p>J&rsquo;ai eu l&rsquo;honneur de <a href="http://www.paris-web.fr/2010/programme/html5-cest-maintenant-ie6-inclus.php">présenter</a> à Paris Web 2010 un thème que vous retrouvez souvent sur ce blog : les applications Web. Le titre exact était &laquo;&nbsp;HTML5 c&rsquo;est maintenant (IE6 inclus)&nbsp;&raquo;, ce qui est un clin d&rsquo;oeil au grand écart que les développeurs Web font constamment entre les anciens navigateurs et les nouvelles fonctionnalités.</p>
<p>Il y a <a href="http://braincracking.org/?p=866">une vidéo</a> et <a href="http://www.slideshare.net/jpvincent/html5-now-light">des slides</a> de cette conférence. Mais si vous n&rsquo;avez pas une heure de temps devant vous pour voir la vidéo, sachez qu&rsquo;en préparant cette conférence je suis allé beaucoup plus loin dans les détails concernant HTML5 &#8230; avant de réaliser qu&rsquo;une conférence n&rsquo;est pas faite pour aller dans les détails mais pour faire passer un message.<br />
Voici donc la version &laquo;&nbsp;director&rsquo;s cut&nbsp;&raquo; de la présentation, où est écrit tout ce que j&rsquo;ai du dire à l&rsquo;oral mais supprimer des slides vus à Paris Web :</p>
<p><span id="more-597"></span></p>
<ol>
<li>
<a title="HTML5 maintenant partie 1 : la sémantique" href="http://www.slideshare.net/jpvincent/html5-maintenant-partie-3-la-smantique">HTML5 maintenant partie 1 : la sémantique</a><br />
<iframe style="border:none;width:520px;height:420px;" src="http://braincracking.org/slidesharehtml/embed.php?width=500&#038;url=http://www.slideshare.net/jpvincent/html5-maintenant-partie-3-la-smantique"></iframe>
</li>
<li>
<a title="HTML5 maintenant partie 3 : APIs" href="http://www.slideshare.net/jpvincent/html5-maintenant-partie-3-apis">HTML5 maintenant partie 2 : APIs</a><br />
<iframe style="border:none;width:520px;height:420px;" src="http://braincracking.org/slidesharehtml/embed.php?width=500&#038;url=http://www.slideshare.net/jpvincent/html5-maintenant-partie-3-apis"></iframe>
</li>
<li>
<a title="HTML5 maintenant partie 3 : multimedia" href="http://www.slideshare.net/jpvincent/html5-maintenant-partie-3-multimedia">HTML5 maintenant partie 3 : multimedia</a><br />
<iframe style="border:none;width:520px;height:420px;" src="http://braincracking.org/slidesharehtml/embed.php?width=500&#038;url=http://www.slideshare.net/jpvincent/html5-maintenant-partie-3-multimedia"></iframe></p>
</li>
</ol>
<p>Je serais ravi d&rsquo;exploiter ces slides pour faire des conférences ou des cours plus approfondis sur certaines parties de HTML5, <a href="http://braincracking.org/a-propos/">contactez moi</a> si vous êtes intéressés, que vous organisiez une conférence gratuite ou que vous soyez une école.</p>
<p>Encore merci à Paris Web d&rsquo;exister tout simplement : en discutant avec des experts dans leur domaine et des gens venus se faire un tour d&rsquo;horizon des technos et bonnes pratiques du Web, je me suis rendu compte à quel point cette conférence est de bonne qualité malgré son prix, et comment il peut aider tout le monde se mettre à niveau, le tout dans une humeur bon enfant.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/braincracking?a=-NEHJi_6uwM:n3Lrc9ZXLzo:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/braincracking?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=-NEHJi_6uwM:n3Lrc9ZXLzo:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/braincracking?i=-NEHJi_6uwM:n3Lrc9ZXLzo:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=-NEHJi_6uwM:n3Lrc9ZXLzo:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/braincracking?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=-NEHJi_6uwM:n3Lrc9ZXLzo:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/braincracking?i=-NEHJi_6uwM:n3Lrc9ZXLzo:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=-NEHJi_6uwM:n3Lrc9ZXLzo:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/braincracking?i=-NEHJi_6uwM:n3Lrc9ZXLzo:V_sGLiPBpWU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/braincracking/~4/-NEHJi_6uwM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://braincracking.org/2010/10/15/conference-paris-web-html5-cest-maintenant-ie6-inclus/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		<feedburner:origLink>http://braincracking.org/2010/10/15/conference-paris-web-html5-cest-maintenant-ie6-inclus/</feedburner:origLink></item>
		<item>
		<title>Passer son blog WordPress à la sémantique HTML5 et ARIA</title>
		<link>http://feedproxy.google.com/~r/braincracking/~3/sMaiMq8vq-8/</link>
		<comments>http://braincracking.org/2010/08/27/passer-son-blog-wordpress-a-la-semantique-html5-et-aria/#comments</comments>
		<pubDate>Fri, 27 Aug 2010 14:36:57 +0000</pubDate>
		<dc:creator>jpvincent</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[Accessibilité]]></category>
		<category><![CDATA[ARIA]]></category>
		<category><![CDATA[sémantique]]></category>
		<category><![CDATA[Standards]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://braincracking.org/blog/?p=320</guid>
		<description><![CDATA[HTML5 introduit de nouveaux éléments qui sont parfaits pour ajouter de la sémantique à un blog ou un journal. ARIA fait de même concernant l&#8217;accessibilité aussi étant donné la facilité permise par WordPress pour modifier son markup, il serait dommage de se priver, même si vous êtes un débutant WordPress comme moi. Nous allons donc [...]]]></description>
			<content:encoded><![CDATA[<p><abbr>HTML5</abbr> introduit de nouveaux éléments qui sont parfaits pour ajouter de la sémantique à un blog ou un journal. <abbr>ARIA</abbr> fait de même concernant l&rsquo;accessibilité aussi étant donné la facilité permise par <span lang="en">WordPress</span> pour modifier son <span lang="en">markup</span>, il serait dommage de se priver, même si vous êtes un débutant <span lang="en">WordPress</span> comme moi.  Nous allons donc voir :</p>
<ul>
<li>l&rsquo;utilisation des nouvelles balises <code>&lt;article&gt;, &lt;time&gt;, &lt;nav&gt; ...</code></li>
<li>certains rôles <abbr>ARIA</abbr></li>
<li>les améliorations des formulaires</li>
<li>les ajouts <abbr>JS</abbr>/<abbr>CSS</abbr> à apporter</li>
<li>les fichiers à modifier dans <span lang="en">wordpress</span></li>
</ul>
<p>Le tout bien sur compatible sur tous les navigateurs, IE6 inclus.</p>
<p>Même si vous n&rsquo;êtes pas un utilisateur WordPress, les remarques sur la sémantique HTML5 et les rôles ARIA restent valables quel que soit le site.<br />
<span id="more-320"></span></p>
<h2>Travail préparatoire</h2>
<p>Tout passage à <abbr>HTML5</abbr> doit passer par 2 ajouts à votre site, afin d&rsquo;avoir un comportement normal des nouveaux éléments, que les anciens navigateurs ne pouvaient bien sur pas connaître. Je les reprend de mon précédent article sur <a href="http://braincracking.org/blog/2010/02/08/migrer-un-site-de-production-vers-un-markup-html5/">le passage à <abbr>HTML5</abbr></a>, la situation n&rsquo;ayant pas évolué depuis.</p>
<h3 lang="en">JavaScript</h3>
<p><abbr title="Internet Explorer" lang="en">IE</abbr> ne sait pas styler les éléments inconnus. Heureusement il existe une solution <abbr title="Javascript" lang="en">JS</abbr> reconnue appelée <a lang="en" href="http://remysharp.com/2009/01/07/html5-enabling-script/">HTML5 shim</a> pour contourner ce problème, qui consiste à créer dynamiquement au moins une fois ce nouvel élément. Ceci marche avec <abbr title="Internet Explorer 6">IE6</abbr> et supérieur. Notez que ce code doit être <strong>exécuté obligatoirement dans <code>&lt;HEAD&gt;</code></strong>. Plusieurs choix alors :</p>
<ul>
<li>pour des gains de performances, vous avez enlevé les inclusions de fichiers <abbr title="JavaScript">JS</abbr> du <code>&lt;HEAD&gt;</code>. Il vous faut alors éditer <em><strong>header.php</strong></em> pour rajouter ce script inline, avant <code>&lt;HEAD&gt;</code></li>
<li>vous ou votre thème inclue déjà <span lang="en">modernizr</span>, ce script est déjà inclus dedans. Si <span lang="en">modernizr</span> est dans le <code>&lt;HEAD&gt;</code> vous n&rsquo;avez rien à ajouter</li>
<li>vous avez un fichier javascript global inclus dans le <code>&lt;HEAD&gt;</code>, c&rsquo;est dans ce fichier qu&rsquo;il faut rajouter ces lignes.</li>
</ul>
<pre><code>// inspiré de http://code.google.com/p/html5shim/source/browse/trunk/html5.js
// crée tous les tags HTML5 au moins une fois pour que IE sache les styler
// Commentaires et discussions, voir http://remysharp.com/2009/01/07/html5-enabling-script/
(function(){
	if(!/*@cc_on!@*/0)
		return;
	var e = 'abbr,article,aside,audio,bb,canvas,datagrid,datalist,details,dialog,eventsource,figure,footer,header,hgroup,mark,menu,meter,nav,output,progress,section,time,video'
		.split(',');
	for(var i=0, iTotal = e.length; i&lt;iTotal;i++) {
		document.createElement(e[i]);
	}
})();</code></pre>
<h3>CSS</h3>
<p>Tous les éléments inconnus pour les navigateurs sont de type <code>display:inline</code> par défaut, ce qui peut rapidement casser un <span lang="en">design</span> : si vous passez d&rsquo;une <code>&lt;DIV&gt;</code> à un <code>&lt;ARTICLE&gt;</code>, vous allez être obligé de rétablir <code>display:block</code> pour chaque élément. Il est préférable de s&rsquo;inspirer de la <strong>stratégie des <span lang="en">CSS reset</span></strong> et de <strong>définir un comportement par défaut</strong> à toutes les balises <abbr>HTML5</abbr> possibles. Notez que l&rsquo;on définit également les balises qui devraient être <span lang="en">inline</span>, ceci afin de prévenir le cas où un navigateur déciderait de mettre une des ces balises en <code>display:block</code>.  Dans le <strong>fichier style.css</strong>, après le <span lang="en">CSS reset</span> :</p>
<pre><code>/* tags HTML5 qui se comportent comme des blocs */
article, aside, audio, canvas, datagrid, datalist, details, dialog, figure, footer, header, menu, nav, section, video { display: block; }
/* tags de type en ligne */
abbr, eventsource, mark, meter, time, progress, output, bb { display:inline; }</code></pre>
<h3 lang="en">doctype</h3>
<p>Nous allons maintenant remplacer votre doctype par le désormais célèbre nouveau <span lang="en">doctype <abbr>HTML5</abbr></span>.  dans <strong><em>header.php</em></strong>, première ligne : <code>&lt;!DOCTYPE html&gt;</code>. Vérifiez que votre blog s&rsquo;affiche toujours comme avant sur tous vos navigateurs cible, je n&rsquo;ai jamais entendu que ce nouveau <span lang="en">doctype</span> posait problème. Vous êtes officiellement passé en <abbr>HTML5</abbr> <img src='http://braincracking.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h2>Les articles</h2>
<h3>La sémantique en théorie</h3>
<p>Il y a 4 nouvelles balises toutes trouvées (en plus du <code>&lt;Hx&gt;</code>) qui vont enrichir sémantiquement nos articles. Ce qui change avec <abbr>HTML5</abbr>, c&rsquo;est que non seulement la balise a un sens, mais ce sens peut varier en fonction des éléments parents :</p>
<ul>
<li><code>&lt;ARTICLE&gt;</code> : surpris ? Allons un peu plus loin : la <a href="http://dev.w3.org/html5/spec/Overview.html#the-article-element">définition du W3C</a> dit qu&rsquo;elle représente une section isolable du site, qui peut s&rsquo;autosuffire en dehors du contexte de la page (dans un lecteur RSS par exemple). Cette balise peut aussi être enfant d&rsquo;un autre <code>&lt;ARTICLE&gt;</code>, comme dans l&rsquo;interprétation qu&rsquo;en a fait <a lang="en" href="http://html5doctor.com/the-article-element/">HTML5 Doctor</a>, auquel cas elle pourrait représenter les commentaires relatifs à un article. Nous n&rsquo;allons pas le faire ici car ce point est parfois discuté et cela demande beaucoup plus de modifications dans wordpress car les styles de l&rsquo;articles et des commentaires n&rsquo;ont pas été prévus pour s&rsquo;imbriquer.</li>
<li><code>&lt;HEADER&gt;</code> : cette balise n&rsquo;est pas exclusivement réservée à l&rsquo;en-tête du site ! A l&rsquo;intérieur d&rsquo;un <code>&lt;ARTICLE&gt;</code>, elle sert à repérer les <strong>titres et méta-données de l&rsquo;article</strong> comme la date de publication et le nom de l&rsquo;auteur. Dans WordPress, cela correspond exactement aux éléments avec les classes <code>.entry-title, .entry-header, .author, .published</code> et <code>.comment-count</code></li>
<li><code>&lt;FOOTER&gt;</code> : elle non plus n&rsquo;est pas réservée au pied de page du site. Placée dans un <code>&lt;ARTICLE&gt;</code>, elle marque les informations relatives à l&rsquo;article mais non indispensables, telles que tags et catégories. Dans WordPress, cela correspond aux classes <code>.entry-footer, .entry-categories</code> et <code>.entry-tags</code></li>
<li><code>&lt;TIME&gt;</code> : elle sert à indiquer une date. Rajoutez y l&rsquo;attribut <code>pubdate</code> pour signifier au parseur qu&rsquo;il s&rsquo;agit de la <strong>date de publication de l&rsquo;<code>&lt;ARTICLE&gt;</code> parent</strong>. L&rsquo;attribut <code>datetime</code> doit contenir la date à un <a href="http://dev.w3.org/html5/spec/text-level-semantics.html#the-time-element">format standardisé</a> qui peut varier de &laquo;&nbsp;2010-08-20&Prime; à &laquo;&nbsp;2010-08-20T20:00+09:00&Prime;. PHP à la rescousse : <a href="http://fr.php.net/manual/fr/class.datetime.php#datetime.constants.types">il y a une constante</a> pour ce format qui s&rsquo;appelle <strong><code>DATE_W3C</code></strong> et que vous pouvez passer à la fonction wordpress d&rsquo;affichage de la date.</li>
</ul>
<h3>Le code final :</h3>
<p>Voici le code original simplifié d&rsquo;une installation WordPress 3 avec le thème par défaut :</p>
<pre><code>&lt;div class="hentry" id="post-777"&gt;
	&lt;h2 class="entry-title"&gt;Titre + lien&lt;/h2&gt;
	&lt;div class="entry-meta"&gt;
		&lt;span class="meta-prep meta-prep-author"&gt;Publié le&lt;/span&gt;
		&lt;span class="entry-date"&gt;Vendredi 20 août 2010&lt;/span&gt;
		&lt;span class="author vcard"&gt;Auteur&lt;/span&gt;
	&lt;/div&gt;&lt;!-- .entry-meta --&gt;
	&lt;div class="entry-content"&gt;
		corps de l article
	&lt;/div&gt;&lt;!-- .entry-content --&gt;
	&lt;div class="entry-utility entry-footer"&gt;
		catégories, tags, commentaires ...
	&lt;/div&gt;&lt;!-- .entry-utility --&gt;
&lt;/div&gt;&lt;!-- .hentry --&gt;</code></pre>
<p>notez les très pratiques commentaires qui marquent les balises de fermeture. Nous allons donc :</p>
<ul>
<li><strong>remplacer</strong> la <code>DIV.<em>hentry</em></code> par une balise <code>ARTICLE</code>, en conservant les classes</li>
<li><strong>remplacer</strong> la <code>DIV.<em>entry-utility</em></code> (ou <code>.<em>entry-footer</em></code> dans mon thème) par une balise <code>FOOTER</code>, en conservant les classes</li>
<li><strong>entourer</strong> le &lt;<code>H2&gt;</code> et la <code>DIV.entry-meta</code> par une balise <code>HEADER</code></li>
<li><strong>remplacer</strong> le <code>&lt;H2&gt;</code> par un <code>&lt;H1&gt;</code> : en <abbr>HTML5</abbr>, les <code>Hx</code> sont relatifs à l&rsquo;élément parent pour lequel cela a un sens : <code>&lt;ARTICLE&gt;</code>, <code>&lt;SECTION&gt;</code> ou <code>BODY</code>. Contrairement à certaines recommandations <abbr title="Search Engine Optimization" lang="en">SEO</abbr>, il est donc possible d&rsquo;avoir plusieurs H1 par page</li>
<li>entourer ou <strong>remplacer</strong> le <code>SPAN.entry-date</code> par ce code : <code>&lt;time pubdate datetime="&lt;?php the_time( DATE_W3C ); ?&gt;"&gt; ... &lt;/time&gt;</code></li>
</ul>
<p>pour obtenir ce markup :</p>
<pre><code>&lt;<strong>article</strong> class="hentry" id="post-777"&gt;
	&lt;<strong>header</strong>&gt;
		&lt;<strong>h1</strong> class="entry-title"&gt;Titre + lien&lt;/<strong>h1</strong>&gt;
		&lt;div class="entry-meta"&gt;
			&lt;span class="meta-prep meta-prep-author"&gt;Publié le&lt;/span&gt;
			&lt;<strong>time pubdate datetime</strong>="2010-08-20T11:34:47+00:00"
					class="entry-date"&gt;
				Vendredi 20 août 2010
			&lt;/<strong>time</strong>&gt;
			&lt;span class="author vcard"&gt;Auteur&lt;/span&gt;
		&lt;/div&gt;&lt;!-- .entry-meta --&gt;
	&lt;/<strong>header</strong>&gt;
	&lt;div class="entry-content"&gt;
		corps de l article
	&lt;/div&gt;&lt;!-- .entry-content --&gt;
	&lt;<strong>footer</strong> class="entry-utility entry-footer"&gt;
		catégories, tags, commentaires ...
	&lt;/<strong>footer</strong>&gt;&lt;!-- .entry-utility --&gt;
&lt;/<strong>article</strong>&gt;&lt;!-- .hentry --&gt;</code></pre>
<h3>Que modifier ?</h3>
<p>Il va falloir apporter ces modifications à beaucoup d&rsquo;endroits, voici une liste non exhaustive (selon votre thème) :</p>
<ul>
<li>archive.php</li>
<li>single.php</li>
<li>page.php</li>
<li>index.php</li>
<li>category.php</li>
<li>author.php</li>
<li>tag.php</li>
<li>search.php (à la différence que <code>&lt;ARTICLE&gt;</code> ne doit pas remplacer le <code>&lt;LI&gt;</code> mais être son premier et unique fils)</li>
<li>date.php</li>
</ul>
<p>Je déteste dupliquer le code, donc si vous êtes bons en WordPress vous devriez peut être inclure un template unique d&rsquo;article dans tous ces fichiers, car c&rsquo;est quasiment le même markup à chaque fois. La partie difficile étant bien sur de coder le &laquo;&nbsp;quasiment&nbsp;&raquo; <img src='http://braincracking.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />   Voilà, <strong>vous êtes passé à la sémantique HTML5 sur la partie importante du blog</strong> que sont les articles. Logiquement Google ou d&rsquo;autres programmes devraient utiliser un jour ce standard, au même titre que les <span lang="en">microformats</span>, <span lang="en">microdata</span> ou <abbr>RDFa</abbr> pour comprendre plus facilement votre site et donc proposer des fonctionalités spécifiques à vos lecteurs (un affichage spécifique dans les résultats Google, une meilleure indexation, les navigateurs pourraient mettre en avant l&rsquo;article &#8230;).</p>
<h2><span lang="en"><abbr>HTML5</abbr> Forms</span> et rôles ARIA dans votre layout</h2>
<p>Pour le reste du site, nous allons ajouter plus de sémantique. Notez que les rôles ARIA sont déjà correctement définis dans le thème par défaut, mais ce n&rsquo;est probablement pas celui que vous utilisez, donc je vais les répéter.</p>
<h3>Formulaires</h3>
<p><span lang="en">Forms 2</span> a été renommé en <span lang="en"><abbr>HTML5</abbr></span> Forms et continue de définir de nouveaux types de champs ainsi que d&rsquo;ajouter du comportemental sans JavaScript. Par défaut il n&rsquo;y a pas de JavaScript qui régisse les formulaires de WordPress (commentaires et recherche), on ne perd donc pas de fonctionnalité pour les anciens navigateurs : on en rajoute pour ceux qui supportent <span lang="en"><abbr>HTML5</abbr></span> Forms <img src='http://braincracking.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Si vous voulez ajouter facilement ces fonctionnalités pour pour d&rsquo;autres navigateur sans taper de code <abbr title="javascript">JS</abbr>, vous pouvez partir sur <a href="http://code.google.com/p/webforms2/">la librairie <span lang="en">WebForms2</span></a></p>
<h4>Dans comments.php :</h4>
<ul>
<li>la <code>&lt;DIV&gt;</code> avec l&rsquo;<abbr title="identifiant">id</abbr> <code>#respond</code> devient une <code>&lt;SECTION&gt;</code> : comme une <code>&lt;DIV&gt;</code>, la <code>&lt;SECTION&gt;</code> n&rsquo;a pas de valeur sémantique particulière, sinon qu&rsquo;elle contient un titre, ce qui est ici le cas avec un <code>&lt;H3&gt;</code> comme enfant direct. Ce <code>&lt;H3&gt;</code> est d&rsquo;ailleurs promu au rang de <code>&lt;H1&gt;</code> car c&rsquo;est le titre le plus important de cette <code>&lt;SECTION&gt;</code></li>
<li>dans le formulaire de commentaire, on <strong>modifie le type de 2 champs</strong> : celui de l&rsquo;email et du site Web pour les passer très logiquement en <code>type="email"</code> et <code>type="url"</code>. Cela ne change rien pour la plupart des navigateurs mais outre la lisibilité du code, le seul bénéfice connu actuel est le changement de clavier sur <abbr title="Apple Mobile Operating System">iOS</abbr> &#8230; Mais dans les mois qui viennent, d&rsquo;autres clients pourraient l&rsquo;utiliser pour une meilleure autocomplétion des champs ou pour signaler un type de données invalides. En attendant cela ne coûte rien</li>
<li>rajouter l&rsquo;attribut <code>required</code> ainsi que <code>aria-required="true"</code> aux champs obligatoires (au minimum l&rsquo;email et le champs de commentaires). En code <span lang="en">WordPress</span> cela donne :</li>
</ul>
<pre><code> &lt;input name="email" id="email" <strong>type="email"</strong> value="&lt;?php echo $comment_author_email; ?&gt;" tabindex="2" &lt;?php if ( $req ) echo "<strong>aria-required='true' required</strong>"; ?&gt; /&gt;</code></pre>
<p>Les navigateurs supportant <code>required</code> (<abbr title="Firefox 4">FF4</abbr>, Opéra 9+, <abbr title="Chrome, Safari, Safaris mobiles">Webkits</abbr>) ne laisseront pas l&rsquo;utilisateur valider le formulaire tant qu&rsquo;il n&rsquo;a pas rempli <strong>correctement</strong> les champs. Voir cette démo <a href="http://devfiles.myopera.com/articles/67/example.html">faite par Opéra</a>. </p>
<p>Vous pouvez ensuite styler en CSS grâce aux pseudo-sélecteurs les champs non ou mal remplis :</p>
<pre><code>input:invalid,
input:invalid + label {
	background-color : red;
}</code></pre>
<p>Votre code final généré pour la zone de saisie de commentaires devrait ressembler à ceci :</p>
<pre><code>&lt;<strong>section</strong> id="respond"&gt;
	&lt;h3 id="leave-a-reply"&gt;Laisser un commentaire&lt;/h3&gt;
	&lt;!--BEGIN #comment-form--&gt;
	&lt;form action="..."&gt;
		&lt;!--BEGIN #form-section-url--&gt;
		&lt;div class="form-section" id="form-section-url"&gt;
			&lt;input <strong>type="url" required="required" aria-required="true"</strong> value="http://braincracking.org/" id="url" name="url"&gt;
			&lt;label class="required" for="url"&gt;Site Web&lt;/label&gt;
		&lt;!--END #form-section-url--&gt;
		&lt;/div&gt;
	../..
	&lt;!--END #comment-form--&gt;
	&lt;/form&gt;
&lt;!--END #respond--&gt;
&lt;/<strong>section</strong>&gt; </code></pre>
<p>Notez que l&rsquo;on pourrait passer de même tous les widgets avec <code>&lt;SECTION&gt;</code> et leur titre en <code>&lt;H1&gt;</code>.</p>
<p><strong>Dans <strong>searchform.php</strong> :</strong></p>
<p>Si votre thème n&rsquo;a peut-être pas ce fichier ou équivalent, sachez que le formulaire de recherche par défaut se trouve dans <strong><em>general-template.php</em></strong>, dans la fonction <code>get_search_form</code>.  Nous allons rajouter ici 3 choses :</p>
<ul>
<li>le rôle <abbr>ARIA</abbr> sur le formulaire lui même : <code>&lt;form role="search" ...&gt;</code></li>
<li>le type <span lang="en">&laquo;&nbsp;search&nbsp;&raquo;</span> sur le champs de formulaire : <code>&lt;input type="search" /&gt;</code>. Notez que sous les webkits sur Mac OS, votre champs apparaît stylé comme <span lang="en">Spotlight</span> : arrondi avec une croix d&rsquo;annulation</li>
<li>un <span lang="en">&laquo;&nbsp;placeholder&nbsp;&raquo;</span>, grand classique du Web : un texte par défaut disparaît lorsque l&rsquo;on clique sur le champs et ré-apparaît si rien n&rsquo;a été écrit : <code>&lt;input placeholder="Rechercher" /&gt;</code></li>
</ul>
<p>ce qui se devrait se traduire par ce code final :</p>
<pre><code>&lt;form <strong>role="search" </strong>action="http://braincracking.org/blog" method="get" class="searchform"&gt;
	&lt;input <strong>type="search" placeholder</strong>="Rechercher" name="s" class="search" /&gt;
	&lt;button type="submit" class="search-btn"&gt;Rechercher&lt;/button&gt;
&lt;!--END #searchform--&gt;
&lt;/form&gt; </code></pre>
<h3 lang="en">Layout</h3>
<h4>sidebar.php</h4>
<p>Ceci affiche la ou les colonnes latérales, qui est donc un contenu sans forcément un rapport direct avec le contenu principal du site. <abbr>ARIA</abbr> et <abbr>HTML5</abbr> ont tout prévu pour cela : <code>role="complementary"</code> et balise <code>&lt;ASIDE&gt;</code>. Vous devez donc modifier une (ou plusieurs selon le thème) <code>&lt;DIV&gt;</code> parentes pour obtenir ceci :</p>
<pre><code>
&lt;<strong>aside role="complementary"</strong> id="..." class="..."&gt;
	widget et contenus relatifs
&lt;/<strong>aside</strong>&gt;
</code></pre>
<h4>header.php</h4>
<p>Nous avons déjà modifié ce fichier pour y rajouter le <span lang="en">doctype</span>, notre <abbr title="Javascript">JS</abbr> et le <abbr>CSS</abbr> afin de préparer le blog à <abbr>HTML5</abbr>. Passons maintenant aux ajouts sémantiques :</p>
<ul>
<li>la balise <code>&lt;HEADER&gt;</code>, pour marquer cette zone</li>
<li>la balise <code>&lt;NAV&gt;</code> pour indiquer une zone de liens. Selon votre thème, cela peut être la liste des catégories ou des pages à part. Nous lui ajouterons le rôle <abbr>ARIA</abbr> <code>navigation</code> qui lui correspond exactement</li>
<li>le rôle <abbr>ARIA</abbr> <code>banner</code> qui signale titre et logo</li>
<li>si votre formulaire de recherche n&rsquo;est pas déjà modifié, c&rsquo;est le moment de rajouter <code>role="search"</code> sur le formulaire et <code>type="search" placeholder="Rechercher"</code> dans le champs de recherche</li>
</ul>
<p>Les résultats varient grandement selon le thème, mais voici un exemple simplifié à partir du code du thème par défaut WordPress 3 :</p>
<pre><code>&lt;<strong>header</strong> class="header"&gt;
	&lt;<strong>nav</strong> id="access" <strong>role="navigation"</strong>&gt;
		&lt;ul class="nav"&gt;
			&lt;li class="current_page_item"&gt;&lt;a href="http://braincracking.org/blog/" title="Accueil"&gt;Accueil&lt;/a&gt;&lt;/li&gt;
			&lt;li class="page_item page-item-2"&gt;&lt;a href="http://braincracking.org/blog/a-propos/" title="A propos"&gt;A propos&lt;/a&gt;&lt;/li&gt;
		&lt;/ul&gt;
	&lt;/<strong>nav</strong>&gt;
	&lt;!-- END #access --&gt;
	&lt;div id="branding" <strong>role="banner"</strong>&gt;
		&lt;h1 id="blog_header"&gt;&lt;a href="http://braincracking.org/blog"&gt;BrainCracking&lt;/a&gt;&lt;/h1&gt;
	&lt;/div&gt; &lt;!-- #branding --&gt;
&lt;/<strong>header</strong>&gt;&lt;!-- #header --&gt;
</code></pre>
<h4>footer.php</h4>
<p>Là aussi, sans grande surprise nous allons utiliser la balise <code>&lt;FOOTER&gt;</code> ainsi que le <code>role=contentinfo</code> qui sont tous deux faits pour baliser une zone contenant copyrights, liens vers mentions légales et autres textes <strong>relatifs au site, mais pas forcément au contenu de cette page</strong>. <strong>Attention</strong>, chez <span lang="en">WordPress</span> cela ne correspond pas exactement à la <code>DIV id="footer"</code> du template par défaut, celle ci contenant également d&rsquo;autres widgets.<br />
Concrètement :</p>
<pre><code>&lt;!--BEGIN #footer--&gt;
&lt;div id="footer"&gt;
	&lt;div id="footer-widget-area"&gt;
		code généré par les widgets
	&lt;/div&gt;&lt;!-- End #footer-widget-area --&gt;
	&lt;<strong>footer</strong> id="copyright" <strong>role="contentinfo"</strong>&gt;© 2009-2010
		&lt;nav role="navigation"&gt;
			Liens vers mentions légales, vie privée, qui somme nous ...
		&lt;/nav&gt;
	&lt;/<strong>footer</strong>&gt;
&lt;!--END #footer--&gt;
&lt;/div&gt;</code></pre>
<p>Notez que pour ceux qui font des liens, on peut tout à fait rajouter la balise <code>&lt;NAV&gt;</code>.</p>
<h2>Conclusion</h2>
<p>Avec ce tutoriel et 2 à 3 heures de travail, vous pouvez passez assez facilement à la sémantique <abbr>HTML5</abbr> sur votre blog dès aujourd&rsquo;hui. En fait en le codant, il devient même évident que les spécifications <strong><abbr>HTML5</abbr> et <abbr>ARIA</abbr> on été influencées par la sémantique <span lang="en">WordPress</span></strong> tant la correspondance est facile.</p>
<p>Du côté de <abbr>HTML5</abbr>, il est probable que sur ce thème par défaut, <span lang="en">WordPress</span> ait préféré faire l&rsquo;impasse pour ne pas dépendre de Javascript ou de spécifications qui ne sont pas totalement fixées. Je pense personnellement que ces 2 limites ne sont pas un problème :</p>
<ul>
<li>les éléments que j&rsquo;ai cité ici ont tous ont été largement discutés, et il est peu probable que le <abbr>W3C</abbr> revienne dessus. Si c&rsquo;est cependant le cas les modifications à faire ne sont pas complexes</li>
<li> j&rsquo;estime la population avec <abbr title="Internet Explorer">IE</abbr> et javascript désactivé comme négligeable, au pire ils auront un design cassé mais sur un blog le contenu principal (l&rsquo;article) restera exploitable.</li>
</ul>
<p>Les rôles <abbr>ARIA</abbr> sont déjà inclus dans le thème par défaut de <span lang="en">WordPress</span> 3, mais nombre de thèmes ont oublié de les répliquer. En créant ce blog, je cherchais des thèmes exploitant déjà la sémantique <abbr>HTML5</abbr>, mais ils sont peu nombreux donc le choix en graphismes est limité, et à l&rsquo;heure d&rsquo;écrire cet article aucun n&rsquo;exploitait autant <abbr>ARIA</abbr> et <abbr>HTML5</abbr>.</p>
<p>Références, outils, remerciements :</p>
<ul>
<li>2 thèmes WordPress tout faits (mais incomplets) : <a href="http://wordpress.org/extend/themes/toolbox">Toolbox</a> et <a href="http://wordpress.org/extend/themes/justcss">JustCSS</a></li>
<li>les <a href="http://dev.w3.org/html5/spec/Overview.html#the-nav-element">specifications HTML5</a> et <a href="http://www.w3.org/TR/wai-aria/">ARIA</a></li>
<li>la <a href="http://devfiles.myopera.com/articles/67/example.html">démo d&rsquo;Opéra</a> sur les formulaires HTML5</li>
<li><a href="http://html5doctor.com/article-archive/">HTML5 Doctor</a> pour l&rsquo;ensemble de leur oeuvre d&rsquo;explication des specifications</li>
<li>Merci à <a href="http://blog.johanbleuzen.fr/">Johan Bleuzen</a> d&rsquo;avoir relu et validé la partie WordPress</li>
<li>les validateurs <a href="http://validator.w3.org/check?uri=http%3A%2F%2Fbraincracking.org%2Fblog%2F">W3C</a> et <a href="http://html5.validator.nu/?doc=http://braincracking.org/blog&amp;showsource=yes">WHATWG</a> que passe maintenant <a href="http://braincracking.org">braincracking.org</a></li>
<li>le plugin Wave pour <a href="http://wave.webaim.org/?lang=en">vérifier ARIA</a> sur son site</li>
<li>le <a href="http://code.google.com/p/h5o/">bookmarklet h5o</a> pour analyser une page HTML5 selon l&rsquo;algorithme W3C</li>
</ul>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/braincracking?a=sMaiMq8vq-8:Md2SllJaqaM:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/braincracking?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=sMaiMq8vq-8:Md2SllJaqaM:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/braincracking?i=sMaiMq8vq-8:Md2SllJaqaM:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=sMaiMq8vq-8:Md2SllJaqaM:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/braincracking?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=sMaiMq8vq-8:Md2SllJaqaM:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/braincracking?i=sMaiMq8vq-8:Md2SllJaqaM:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=sMaiMq8vq-8:Md2SllJaqaM:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/braincracking?i=sMaiMq8vq-8:Md2SllJaqaM:V_sGLiPBpWU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/braincracking/~4/sMaiMq8vq-8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://braincracking.org/2010/08/27/passer-son-blog-wordpress-a-la-semantique-html5-et-aria/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<feedburner:origLink>http://braincracking.org/2010/08/27/passer-son-blog-wordpress-a-la-semantique-html5-et-aria/</feedburner:origLink></item>
		<item>
		<title>bienvenue sur braincracking.org</title>
		<link>http://feedproxy.google.com/~r/braincracking/~3/NPz9UByBndU/</link>
		<comments>http://braincracking.org/2010/08/17/bienvenue-sur-braincracking-org/#comments</comments>
		<pubDate>Tue, 17 Aug 2010 08:45:13 +0000</pubDate>
		<dc:creator>jpvincent</dc:creator>
				<category><![CDATA[La vie tout ça]]></category>

		<guid isPermaLink="false">http://braincracking.org/blog/?p=291</guid>
		<description><![CDATA[Après 9 mois d&#8217;existence de jpv.typepad.com, il était temps de trouver un nom de domaine et une plate-forme correcte pour ce blog. Bienvenue donc sur ce nouveau nom de domaine, voici les améliorations : un moteur de recherche et des tags pour parcourir les 145 revues de presse couvrant l&#8217;actualité du développement d&#8217;applications Web. Cela commençait [...]]]></description>
			<content:encoded><![CDATA[<p>Après 9 mois d&rsquo;existence de jpv.typepad.com, il était temps de trouver un nom de domaine et une plate-forme correcte pour ce blog. Bienvenue donc sur ce nouveau nom de domaine, voici les améliorations :</p>
<ul>
<li><strong>un moteur de recherche et des tags </strong>pour parcourir les 145 revues de presse couvrant l&rsquo;actualité du développement d&rsquo;applications Web. Cela commençait à faire du contenu intéressant et au bout de quelques mois, je me suis rendu compte que <strong>j&rsquo;utilisais beaucoup le moteur de recherche</strong> (de mon lecteur de RSS : thunderbird) pour retrouver d&rsquo;anciens articles et tutoriaux, et que mes commentaires de l&rsquo;époque m&rsquo;aidaient en plus à retrouver rapidement la conclusion, en plus de mettre pas mal de sémantique. Si <strong>ça me sert dans mon travail quotidien</strong>, ça vous sera forcément utile aussi, et la version gratuite de typepad que j&rsquo;utilisais ne permet pas de mettre un moteur de recherche</li>
<li>un <strong>système de commentaires</strong> plus facile : une <strong>centaine de commentaires</strong> ont également été migrés mais je trouvais que le système typepad de commentaires était très contraignant : j&rsquo;en apprend beaucoup grâce à vos commentaires et vos points de vue, en plus de l&rsquo;impression rassurante de ne pas être seul au monde <img src='http://braincracking.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Le système de commentaires plus engageant de WordPress devrait donc faciliter la communication.</li>
<li><strong>d&rsquo;autres auteurs ?</strong> le nom de domaine jpv.typepad.com n&rsquo;encourageait pas vraiment à contribuer, car ça donnait l&rsquo;impression de travailler pour moi. Hors ce blog n&rsquo;est pas pour me promouvoir moi (je ne suis ni freelance ni en recherche de poste) mais pour remplir un vide : je ne connais pas d&rsquo;autre revue de presse en français sur les thèmes que vous trouvez généralement ici : les features d&rsquo;<strong>HTML5</strong>, un peu de <strong>CSS3</strong>, les <strong>performances Web</strong> et l&rsquo;utilisation avancée de <strong>JavaScript</strong>. Je recherche donc <strong>d&rsquo;autres commentateurs de l&rsquo;actualité</strong>, ainsi que des articles originaux sur des points précis. Je recherche également quelqu&rsquo;un qui pourrait <strong>traduire les articles en anglais</strong>, voir la revue de presse</li>
<li>customisons : le passage sur un hébergement normal, avec un wordpress qui est une plateforme impressionante de customisation va me permettre un peu plus de liberté dans le code des démos des articles, jusqu&rsquo;ici hébergées sur jsfiddle.net. Et accessoirement je vais pouvoir un peu jouer avec CSS3, chose que je ne me permet pas au travail, tout en mettant de la sémantique HTML5 et de la performance sur ce blog</li>
</ul>
<p>L&rsquo;url du fil RSS officiel restera <a href="http://feeds.feedburner.com/braincracking">http://feeds.feedburner.com/braincracking</a>, si vous aviez souscrit à <a href="http://jpv.typepad.com/blog/rss.xml">http://jpv.typepad.com/blog/rss.xml</a>, mettez à jour vos lecteurs RSS <img src='http://braincracking.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/braincracking?a=NPz9UByBndU:SFcMV33_r1s:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/braincracking?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=NPz9UByBndU:SFcMV33_r1s:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/braincracking?i=NPz9UByBndU:SFcMV33_r1s:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=NPz9UByBndU:SFcMV33_r1s:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/braincracking?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=NPz9UByBndU:SFcMV33_r1s:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/braincracking?i=NPz9UByBndU:SFcMV33_r1s:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=NPz9UByBndU:SFcMV33_r1s:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/braincracking?i=NPz9UByBndU:SFcMV33_r1s:V_sGLiPBpWU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/braincracking/~4/NPz9UByBndU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://braincracking.org/2010/08/17/bienvenue-sur-braincracking-org/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://braincracking.org/2010/08/17/bienvenue-sur-braincracking-org/</feedburner:origLink></item>
		<item>
		<title>inclusion performante de javascript, la mini-conférence</title>
		<link>http://feedproxy.google.com/~r/braincracking/~3/QYadg13ZO6A/</link>
		<comments>http://braincracking.org/2010/07/22/inclusion-performante-de-javascript-la-mini-conference/#comments</comments>
		<pubDate>Thu, 22 Jul 2010 07:58:47 +0000</pubDate>
		<dc:creator>jpvincent</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Performances]]></category>
		<category><![CDATA[conférence]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Perfs]]></category>

		<guid isPermaLink="false">http://braincracking.org/blog/2010/07/22/inclusion-performante-de-javascript-la-mini-conference/</guid>
		<description><![CDATA[Pas de revue de presse ces 2 derniers jours car j&#8217;ai du préparer une mini conférence de 20 minutes et les sujets performances demandent énormément de recherches et de validation Voici donc mes slides en ligne (PDF ici) de la soirée performance de hier, organisé par Eric Daspet et hébergé (et alcoolisé) par Octo. L&#8217;idée était d&#8217;explorer [...]]]></description>
			<content:encoded><![CDATA[<p>Pas de revue de presse ces 2 derniers jours car j&rsquo;ai du préparer une mini conférence de 20 minutes et les sujets performances demandent énormément de recherches et de validation <img src='http://braincracking.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Voici donc <a href="http://bit.ly/jpv_inclure_js_perf">mes slides en ligne</a> (<a href="http://jpv.typepad.com/files/slides-inclusion-js.pdf">PDF ici</a>) de la <a href="https://sites.google.com/a/survol.fr/webperf-user-group/evenements/21-juillet-2010">soirée performance</a> de hier, organisé par <a href="http://eric.daspet.name/">Eric Daspet</a> et hébergé (et alcoolisé) par <a href="http://www.octo.com/">Octo</a>. L&rsquo;idée était d&rsquo;explorer un point particulier des performances Web, le sujet traité ici étant <strong>l&rsquo;inclusion non-obstrusive de JS</strong>. Il y a beaucoup de techniques plus ou moins exotiques, au final je vous ai épargné un listing savant que j&rsquo;ai troqué contre un début de guide pratique d&rsquo;implémentation. Je n&rsquo;ai pas pu estimer de coûts de développement car les sites sont beaucoup trop différents.</p>
<p>Après un rappel des <a href="http://www.webpagetest.org/result/100630_RCH/1/details/">contre-performances</a> des &lt;<em>script</em>&gt; dans le &lt;<em>head</em>&gt; (Voyages-sncf a des serveurs ultra performants qui délivrent du <strong>HTML en 200ms</strong>, mais la <strong>page reste blanche 2s</strong>), rappel des 3 techniques non bloquantes officielles :</p>
<ul>
<li><strong>Inline</strong> : on n&rsquo;y pense plus, et pourtant c&rsquo;est celle qui demande le moins de modification de code. A utiliser pour les pages avec <strong>beaucoup de nouveaux visiteurs</strong>, sans trop de JS (jeux concours, les HP Google, facebook, Yahoo!, Netvibes &#8230;)</li>
<li><strong>Bottom</strong> : déplacer le &lt;<em>script</em>&gt; du &lt;head&gt; à la fin de &lt;<em>body</em>&gt;. A partir de là les difficultés d&rsquo;implémentation commencent car vous avez probablement du JS inline qui avait des dépendances dans le fichier que vous venez de déplacer. 2 hacks possibles alors, l&rsquo;un <a href="http://jpv.typepad.com/blog/2010/05/performances-web-put-scripts-at-the-bottom-oui-mais-comment-.html">mute+eval</a>() que j&rsquo;applique déjà, l&rsquo;autre que je n&rsquo;ai pas exploré qui consisterait à <a href="http://mattsnider.com/javascript/function-hijacking-pattern/">hijacker</a> les fonctions qui seront appellées pour les exécuter plus tard. Si cela n&rsquo;est pas possible, vous êtes bons pour modifier votre code inline, ce qui est en général le moment où le &laquo;&nbsp;projet performances&nbsp;&raquo; tombe à l&rsquo;eau &#8230;</li>
<li><strong>DOM</strong> : la meilleure mais la plus lourde à implémenter, qui consiste à <a href="http://www.ejeliot.com/blog/109">créer dynamiquement</a> des &lt;<em>script</em>&gt; et à y attacher un callback JS contenant le code dont il dépend. C&rsquo;est <strong>la plus pérenne</strong> à mon sens car une fois passé le gros boulot consistant à fixer son JS inline (en général encapsuler le code dans une fonction de callback suffit), alors <strong>le code est extrêmement souple</strong> et résistera aux changements à venir : code JS qui grossit et se complexifie, <strong>découverte de nouvelles techniques</strong> &#8230;</li>
</ul>
<p>Les liens en raccourci dans les slides sont des références que je vous ai déjà partagé, mais vous trouverez aussi quelques références sur le comportement IE6-7 intéressantes si vous êtes plutôt côté R&amp;D</p>
<p>On le voit, sur un site existant <strong>gagner plusieurs secondes (donc de l&rsquo;argent) sur l&rsquo;inclusion des JS est réalisable</strong> mais a un certain prix. Ceux qui sont avantagés sont ceux qui développaient déjà de manière non-obstrusive (HTML d&rsquo;abord, puis CSS, puis JS) et qui organisent déjà bien leur code JS (une classe ou un ensemble de méthodes par fichiers par exemple).</p>
<p>Si vous n&rsquo;arrivez pas à faire passer un projet d&rsquo;un bloc malgré vos arguments financiers, passez au moins doucement votre code à la méthode DOM au fur et à mesure de la maintenance de votre site, tout évolution future sera moins pénible <img src='http://braincracking.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Et <strong>avant cela</strong>, il vous faut implémenter <a href="http://developer.yahoo.com/performance/rules.html">des techniques</a> <strong>tout aussi efficaces et moins chères</strong>, comme la compression gzip, la concaténation des CSS/JS et surtout la gestion du cache navigateur.</p>
<p>Articles et liens partagés via <a href="http://feeds.feedburner.com/braincracking">RSS</a>, <a href="http://twitter.com/theystolemynick">Twitter</a>, Facebook (<a href="http://www.facebook.com/profile.php?id=100001201663878&amp;v=wall">twitter + blog</a> ou <a href="http://www.facebook.com/pages/Brain-Cracking/127049627331612?v=wall#!/pages/Brain-Cracking/127049627331612?v=wall">blog seul</a>), <a href="http://identi.ca/braincracking">identi.ca</a>, <a href="http://delicious.com/braincracking">Delicious</a>,<br />
<a href="http://feedburner.google.com/fb/a/mailverify?uri=braincracking&amp;loc=en_US">Mail</a>.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/braincracking?a=QYadg13ZO6A:v90Yv-m-6uQ:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/braincracking?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=QYadg13ZO6A:v90Yv-m-6uQ:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/braincracking?i=QYadg13ZO6A:v90Yv-m-6uQ:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=QYadg13ZO6A:v90Yv-m-6uQ:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/braincracking?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=QYadg13ZO6A:v90Yv-m-6uQ:-BTjWOF_DHI"><img src="http://feeds.feedburner.com/~ff/braincracking?i=QYadg13ZO6A:v90Yv-m-6uQ:-BTjWOF_DHI" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/braincracking?a=QYadg13ZO6A:v90Yv-m-6uQ:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/braincracking?i=QYadg13ZO6A:v90Yv-m-6uQ:V_sGLiPBpWU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/braincracking/~4/QYadg13ZO6A" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://braincracking.org/2010/07/22/inclusion-performante-de-javascript-la-mini-conference/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://braincracking.org/2010/07/22/inclusion-performante-de-javascript-la-mini-conference/</feedburner:origLink></item>
	</channel>
</rss>
