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

<channel>
	<title>High Performance Web Sites</title>
	<atom:link href="http://www.stevesouders.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.stevesouders.com/blog</link>
	<description>Essential knowledge for making your web pages faster.</description>
	<lastBuildDate>Thu, 02 Feb 2012 01:27:44 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>HTTP Archive: 2011 recap</title>
		<link>http://www.stevesouders.com/blog/2012/02/01/http-archive-2011-recap/</link>
		<comments>http://www.stevesouders.com/blog/2012/02/01/http-archive-2011-recap/#comments</comments>
		<pubDate>Thu, 02 Feb 2012 01:23:04 +0000</pubDate>
		<dc:creator>Steve Souders</dc:creator>
				<category><![CDATA[HTTP Archive]]></category>
		<category><![CDATA[Performance]]></category>

		<guid isPermaLink="false">http://www.stevesouders.com/blog/?p=2399</guid>
		<description><![CDATA[I started the HTTP Archive back in October 2010. It&#8217;s hard to believe it&#8217;s been that long. The project is going well: The number of websites archived has grown from ~15K to ~55K. (Our goal for this year is 1M!) In May we partnered with Blaze.io to launch the HTTP Archive Mobile. In June we [...]]]></description>
			<content:encoded><![CDATA[<p>I started the <a href="http://httparchive.org/">HTTP Archive</a> back in October 2010. It&#8217;s hard to believe it&#8217;s been that long. The project is going well:</p>
<ul>
<li>The number of websites archived has grown from ~15K to ~55K. (Our goal for this year is 1M!)</li>
<li>In May we partnered with <a href="http://blaze.io/">Blaze.io</a> to launch the <a href="http://mobile.httparchive.org/">HTTP Archive Mobile</a>.</li>
<li>In June we merged with the <a href="http://archive.org/">Internet Archive</a>.</li>
<li>Joining the Internet Archive allowed us to accept financial support from our incredible sponsors: <a title="Google" href="http://www.google.com/">Google</a>, <a title="Mozilla" href="http://www.mozilla.org/firefox">Mozilla</a>, <a title="New Relic" href="http://www.newrelic.com/">New Relic</a>, <a title="O'Reilly Media" href="http://oreilly.com/">O’Reilly Media</a>, <a href="http://www.etsy.com/">Etsy</a>, <a title="Strangeloop Networks" href="http://www.strangeloopnetworks.com/">Strangeloop</a>, and <a title="dynaTrace Software" href="http://www.dynatrace.com/">dynaTrace Software</a>. Last month <a href="http://torbit.com/">Torbit</a> became our newest sponsor.</li>
<li>As of last week we&#8217;ve completely moved to our new data center, <a href="http://www.isc.org/">ISC</a>.</li>
</ul>
<p>I&#8217;m pleased with how the WPO community has contributed to make the HTTP Archive possible. The project wouldn&#8217;t have been possible without <a href="https://twitter.com/#%21/patmeenan">Pat Meenan</a> and his ever impressive and growing <a href="http://webpagetest.org/">WebPagetest</a> framework. A number of people have contributed to the <a href="http://code.google.com/p/httparchive/source/browse">open source code</a> including <a href="http://www.jonathanklein.net/">Jonathan Klein</a>, <a href="http://yusuketsutsumi.com/">Yusuke Tsutsumi</a>, <a href="http://www.ioncannon.net/">Carson McDonald</a>, <a href="http://jbyers.com/">James Byers</a>, <a href="http://greenido.wordpress.com/">Ido Green</a>, Mike Pfirrmann, Guy Leech, and <a href="https://twitter.com/#%21/stephenhay">Stephen Hay</a>.</p>
<p>This is our first complete calendar year archiving website statistics. I want to start a tradition of doing an annual recap of insights from the HTTP Archive.</p>
<h2>2011 vs 2012</h2>
<p>The most noticeable trend during 2011 was the size of websites and resources. Table 1 shows the transfer size of content types for the average website. For example, &#8220;379kB&#8221; is the total size of images downloaded for an average website. (Since the sample of websites changed during the year, these stats are based on the <a href="http://httparchive.org/trends.php?s=intersection&amp;minlabel=Jan+31+2011&amp;maxlabel=Jan+15+2012">intersection trends</a> for 11,910 websites that were in every batch run.)</p>
<table style="padding-bottom: 1em; margin-left: auto; margin-right: auto;" border="0" cellspacing="0" cellpadding="0" align="center">
<tbody>
<tr>
<td style="text-align: center; font-weight: bold; padding-bottom: 0.5em;" colspan="4">Table 1. Transfer Size by Content Type</td>
</tr>
<tr>
<th style="padding: 0 0 2px 0;"></th>
<th style="padding: 0 0 2px 16px;">Jan 2011</th>
<th style="padding: 0 0 2px 16px;">Jan 2012</th>
<th style="padding: 0 0 2px 16px;">change</th>
</tr>
<tr>
<td style="padding-top: 2px; padding-bottom: 2px; border-top: 1px solid #CCC; text-align: left; padding-left: 4px;">HTML</td>
<td style="padding-top: 2px; padding-bottom: 2px; text-align: right; border-top: 1px solid #CCC; padding-right: 4px;">31kB</td>
<td style="padding-top: 2px; padding-bottom: 2px; text-align: right; border-top: 1px solid #CCC; padding-right: 4px;">34kB</td>
<td style="padding-top: 2px; padding-bottom: 2px; text-align: right; border-top: 1px solid #CCC; padding-right: 4px;">+10%</td>
</tr>
<tr style="background: #EEE;">
<td style="padding-top: 2px; padding-bottom: 2px; border-top: 1px solid #CCC; text-align: left; padding-left: 4px;">JavaScript</td>
<td style="padding-top: 2px; padding-bottom: 2px; text-align: right; border-top: 1px solid #CCC; padding-right: 4px;">110kB</td>
<td style="padding-top: 2px; padding-bottom: 2px; text-align: right; border-top: 1px solid #CCC; padding-right: 4px;">158kB</td>
<td style="padding-top: 2px; padding-bottom: 2px; text-align: right; border-top: 1px solid #CCC; padding-right: 4px;">+44%</td>
</tr>
<tr>
<td style="padding-top: 2px; padding-bottom: 2px; border-top: 1px solid #CCC; text-align: left; padding-left: 4px;">CSS</td>
<td style="padding-top: 2px; padding-bottom: 2px; text-align: right; border-top: 1px solid #CCC; padding-right: 4px;">26kB</td>
<td style="padding-top: 2px; padding-bottom: 2px; text-align: right; border-top: 1px solid #CCC; padding-right: 4px;">31kB</td>
<td style="padding-top: 2px; padding-bottom: 2px; text-align: right; border-top: 1px solid #CCC; padding-right: 4px;">+19%</td>
</tr>
<tr style="background: #EEE;">
<td style="padding-top: 2px; padding-bottom: 2px; border-top: 1px solid #CCC; text-align: left; padding-left: 4px;">Images</td>
<td style="padding-top: 2px; padding-bottom: 2px; text-align: right; border-top: 1px solid #CCC; padding-right: 4px;">379kB</td>
<td style="padding-top: 2px; padding-bottom: 2px; text-align: right; border-top: 1px solid #CCC; padding-right: 4px;">459kB</td>
<td style="padding-top: 2px; padding-bottom: 2px; text-align: right; border-top: 1px solid #CCC; padding-right: 4px;">+21%</td>
</tr>
<tr>
<td style="padding-top: 2px; padding-bottom: 2px; border-top: 1px solid #CCC; text-align: left; padding-left: 4px;">Flash</td>
<td style="padding-top: 2px; padding-bottom: 2px; text-align: right; border-top: 1px solid #CCC; padding-right: 4px;">71kB</td>
<td style="padding-top: 2px; padding-bottom: 2px; text-align: right; border-top: 1px solid #CCC; padding-right: 4px;">64kB</td>
<td style="padding-top: 2px; padding-bottom: 2px; text-align: right; border-top: 1px solid #CCC; padding-right: 4px;">-10%</td>
</tr>
<tr style="background: #EEE;">
<td style="padding-top: 2px; padding-bottom: 2px; border-top: 1px solid #CCC; text-align: left; padding-left: 4px;">total</td>
<td style="padding-top: 2px; padding-bottom: 2px; text-align: right; border-top: 1px solid #CCC; padding-right: 4px;">638kB</td>
<td style="padding-top: 2px; padding-bottom: 2px; text-align: right; border-top: 1px solid #CCC; padding-right: 4px;">773kB</td>
<td style="padding-top: 2px; padding-bottom: 2px; text-align: right; border-top: 1px solid #CCC; padding-right: 4px;">+21%</td>
</tr>
</tbody>
</table>
<p>One takeaway from this data is that images make up a majority of the bytes downloaded for websites (59%). Also, images are the second fastest growing content type for desktop and the #1 fastest growing content type for <a href="http://mobile.httparchive.org/trends.php?s=intersection&amp;minlabel=Jun+1+2011&amp;maxlabel=Jan+15+2012#bytesImg&amp;reqImg">mobile</a>. These two observations highlight the need for more performance optimizations for images. Many websites would benefit from <a href="http://code.google.com/speed/page-speed/docs/payload.html#CompressImages">losslessly compressing</a> their images with existing tools. <a href="http://code.google.com/speed/webp/">WebP</a> is another candidate for reducing image size.</p>
<p>A second takeaway is the tremendous growth in JavaScript size &#8211; up 44% over the course of the year. The amount of JavaScript grew more than twice as much as the next closest type of content (images). Parsing and executing JavaScript blocks the UI thread and makes websites slower. More JavaScript makes the problem worse. Downloading scripts also <a href="http://www.stevesouders.com/blog/2009/04/27/loading-scripts-without-blocking/">causes havoc</a> with website performance, so the fact that the <a href="http://httparchive.org/trends.php?s=intersection&amp;minlabel=Jan+31+2011&amp;maxlabel=Jan+15+2012#bytesJS&amp;reqJS">number of scripts on the average page</a> grew from 11 to 13 is also a concern.</p>
<p style="text-align: center;"><img class="alignnone" title="Transfer Size 2011 vs 2012" src="http://stevesouders.com/images/ha-xfer-size-2011-2012.png" alt="" width="480" height="274" /></p>
<p>On a positive note, the amount of Flash being downloaded dropped 10%. Sadly, the <a href="http://httparchive.org/trends.php?s=intersection&amp;minlabel=Jan+31+2011&amp;maxlabel=Jan+15+2012#perFlash">number of sites using Flash</a> only dropped from 44% to 43%, but at least those swfs are downloading faster.</p>
<h2>Adoption of Best Practices</h2>
<p>I personally love the HTTP Archive for tracking the adoption of web performance best practices. Some trends year-over-year include:</p>
<ul>
<li>The percent of resources that had <a href="http://httparchive.org/trends.php?s=intersection&amp;minlabel=Jan+31+2011&amp;maxlabel=Jan+15+2012#maxageNull">caching headers</a> grew from 42% to 46%. It&#8217;s great that the use of caching is increasing, but the fact that 54% of requests still don&#8217;t have any caching headers is a missed opportunity.</li>
<li>Sites using the <a href="http://httparchive.org/trends.php?s=intersection&amp;minlabel=Jan+31+2011&amp;maxlabel=Jan+15+2012#perGlibs">Google Libraries API</a> jumped from 10% to 16%. Using a CDN with distributed locations and the ability to leverage caching across websites make this a positive for web performance.</li>
<li>On the downside, <a href="http://httparchive.org/trends.php?s=intersection&amp;minlabel=Jan+31+2011&amp;maxlabel=Jan+15+2012#perRedirects">websites with at least one redirect</a> grew from 59% to 66%.</li>
<li>Websites using <a href="http://httparchive.org/trends.php?s=intersection&amp;minlabel=Jan+31+2011&amp;maxlabel=Jan+15+2012#perFonts">custom fonts</a> quadrupled from 2% to 8%. I&#8217;ve written about the <a href="http://www.stevesouders.com/blog/2010/06/01/frontend-spof/">performance dangers of custom fonts</a>. Just today I did a performance analysis of <a href="http://www.mauirippers.com/">Maui Rippers</a> and discovered the reason the site <a href="http://www.webpagetest.org/video/compare.php?tests=120131_EH_32NWY-r:2-c:0">didn&#8217;t render for 6+ seconds</a> was a 280K font file.</li>
</ul>
<p>It&#8217;s compelling to see how best practices are adopted by the top websites as compared to more mainstream websites. Table 2 shows various stats for the top 100 and top 1000 websites, as well as all 53,614 websites in the last batch run.</p>
<table style="padding-bottom: 1em; margin-left: auto; margin-right: auto;" border="0" cellspacing="0" cellpadding="0" align="center">
<tbody>
<tr>
<td style="text-align: center; font-weight: bold; padding-bottom: 0.5em;" colspan="4">Table 2. Best Practices for Top 100, Top 1000, All</td>
</tr>
<tr>
<th style="padding: 0 0 2px 0;"></th>
<th style="padding: 0 0 2px 16px;">Top 100</th>
<th style="padding: 0 0 2px 16px;">Top 1000</th>
<th style="padding: 0 0 2px 16px;">  All</th>
</tr>
<tr>
<td style="padding-top: 2px; padding-bottom: 2px; border-top: 1px solid #CCC; text-align: left; padding-left: 4px;">total size</td>
<td style="padding-top: 2px; padding-bottom: 2px; text-align: right; border-top: 1px solid #CCC; padding-right: 4px;">509kB</td>
<td style="padding-top: 2px; padding-bottom: 2px; text-align: right; border-top: 1px solid #CCC; padding-right: 4px;">805kB</td>
<td style="padding-top: 2px; padding-bottom: 2px; text-align: right; border-top: 1px solid #CCC; padding-right: 4px;">962kB</td>
</tr>
<tr style="background: #EEE;">
<td style="padding-top: 2px; padding-bottom: 2px; border-top: 1px solid #CCC; text-align: left; padding-left: 4px;">total requests</td>
<td style="padding-top: 2px; padding-bottom: 2px; text-align: right; border-top: 1px solid #CCC; padding-right: 4px;">57</td>
<td style="padding-top: 2px; padding-bottom: 2px; text-align: right; border-top: 1px solid #CCC; padding-right: 4px;">90</td>
<td style="padding-top: 2px; padding-bottom: 2px; text-align: right; border-top: 1px solid #CCC; padding-right: 4px;">86</td>
</tr>
<tr>
<td style="padding-top: 2px; padding-bottom: 2px; border-top: 1px solid #CCC; text-align: left; padding-left: 4px;">caching headers</td>
<td style="padding-top: 2px; padding-bottom: 2px; text-align: right; border-top: 1px solid #CCC; padding-right: 4px;">70%</td>
<td style="padding-top: 2px; padding-bottom: 2px; text-align: right; border-top: 1px solid #CCC; padding-right: 4px;">58%</td>
<td style="padding-top: 2px; padding-bottom: 2px; text-align: right; border-top: 1px solid #CCC; padding-right: 4px;">42%</td>
</tr>
<tr style="background: #EEE;">
<td style="padding-top: 2px; padding-bottom: 2px; border-top: 1px solid #CCC; text-align: left; padding-left: 4px;">use Flash</td>
<td style="padding-top: 2px; padding-bottom: 2px; text-align: right; border-top: 1px solid #CCC; padding-right: 4px;">34%</td>
<td style="padding-top: 2px; padding-bottom: 2px; text-align: right; border-top: 1px solid #CCC; padding-right: 4px;">49%</td>
<td style="padding-top: 2px; padding-bottom: 2px; text-align: right; border-top: 1px solid #CCC; padding-right: 4px;">48%</td>
</tr>
<tr>
<td style="padding-top: 2px; padding-bottom: 2px; border-top: 1px solid #CCC; text-align: left; padding-left: 4px;">custom fonts</td>
<td style="padding-top: 2px; padding-bottom: 2px; text-align: right; border-top: 1px solid #CCC; padding-right: 4px;">6%</td>
<td style="padding-top: 2px; padding-bottom: 2px; text-align: right; border-top: 1px solid #CCC; padding-right: 4px;">9%</td>
<td style="padding-top: 2px; padding-bottom: 2px; text-align: right; border-top: 1px solid #CCC; padding-right: 4px;">8%</td>
</tr>
<tr style="background: #EEE;">
<td style="padding-top: 2px; padding-bottom: 2px; border-top: 1px solid #CCC; text-align: left; padding-left: 4px;">redirects</td>
<td style="padding-top: 2px; padding-bottom: 2px; text-align: right; border-top: 1px solid #CCC; padding-right: 4px;">57%</td>
<td style="padding-top: 2px; padding-bottom: 2px; text-align: right; border-top: 1px solid #CCC; padding-right: 4px;">69%</td>
<td style="padding-top: 2px; padding-bottom: 2px; text-align: right; border-top: 1px solid #CCC; padding-right: 4px;">65%</td>
</tr>
</tbody>
</table>
<p>The overall trend shows that performance best practices drop dramatically outside of the Top 100 websites. The most significant are:</p>
<ul>
<li>Total size goes from 509 kB to 805 kB to 962 kB.</li>
<li>Total number of HTTP requests is similar growing from 57 to 90 and a small decrease to 86 requests.</li>
<li>The use of future caching headers is high for the top 100 at 70%, but then drops to 58% and even further to 42%.</li>
</ul>
<p>The Web has a <a href="http://en.wikipedia.org/wiki/Long_Tail">long tail</a>. It&#8217;s not enough for the top sites to have high performance. <a href="http://www.stevesouders.com/blog/2010/05/07/wpo-web-performance-optimization/">WPO</a> best practices need to find their way to the next tier of websites and on to the brick-and-mortar, mom-and-pop, and niche sites that we all visit. More awareness, more tools, and more automation are the answer. I can&#8217;t wait to read the January 2013 update to this blog post and see how we did. Here&#8217;s to a faster and stronger Web in 2012!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.stevesouders.com/blog/2012/02/01/http-archive-2011-recap/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>JavaScript Performance</title>
		<link>http://www.stevesouders.com/blog/2012/01/13/javascript-performance/</link>
		<comments>http://www.stevesouders.com/blog/2012/01/13/javascript-performance/#comments</comments>
		<pubDate>Sat, 14 Jan 2012 06:09:44 +0000</pubDate>
		<dc:creator>Steve Souders</dc:creator>
				<category><![CDATA[browsers]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[async]]></category>
		<category><![CDATA[browserscope]]></category>
		<category><![CDATA[onload]]></category>
		<category><![CDATA[webpagetest]]></category>

		<guid isPermaLink="false">http://www.stevesouders.com/blog/?p=2375</guid>
		<description><![CDATA[Last night I spoke at the San Francisco JavaScript Meetup. I gave a brand new talk called JavaScript Performance that focuses on script loading and async snippets. The snippet example I chose was the Google Analytics async snippet. The script-loading part of that snippet is only six lines, but a lot of thought and testing [...]]]></description>
			<content:encoded><![CDATA[<p>Last night I spoke at the <a href="http://www.meetup.com/jsmeetup/events/38563112/">San Francisco JavaScript Meetup</a>. I gave a brand new talk called <a href="http://www.slideshare.net/souders/javascript-performance-at-sfjs">JavaScript Performance</a> that focuses on script loading and async snippets. The snippet example I chose was the <a href="http://code.google.com/apis/analytics/docs/tracking/asyncTracking.html">Google Analytics async snippet</a>. The script-loading part of that snippet is only six lines, but a lot of thought and testing went into it. It&#8217;s a great prototype to use if you&#8217;re creating your own async snippet. I&#8217;ll tweet if/when the video of my talk comes out, but in the meantime the slides (<a href="http://www.slideshare.net/souders/javascript-performance-at-sfjs">Slideshare</a>, <a href="http://stevesouders.com/docs/sfjs-20120112.pptx">pptx</a>) do a good job of relaying the information.</p>
<p>There are two new data points from the presentation that I want to call out in this blog post.</p>
<h2>Impact of JavaScript</h2>
<p>The presentation starts by suggesting that JavaScript is typically the #1 place to look for making a website faster. My anecdotal experience supports this hypothesis, but I wanted to try to do some quantitative verification. As often happens, I turned to <a href="http://webpagetest.org/">WebPagetest</a>.</p>
<p>I wanted to test the Alexa Top 100 URLs with and without JavaScript. To load these sites withOUT JavaScript I used WebPagetest&#8217;s &#8220;block&#8221; feature. I entered &#8220;.js&#8221; which tells WebPagetest to ignore every HTTP request with a URL that contains that string. Each website was loaded three times and the median page load time was recorded. I then found the median of all these median page load times.</p>
<p>The median page load <em>with JavaScript</em> is 3.65 seconds. <em>Without JavaScript</em> the page load time drops to 2.487 seconds &#8211; a 31% decrease. (Here&#8217;s the data in WebPagetest: <a title="with JavaScript" href="http://www.webpagetest.org/result/120111_GR_2TW90/">with JavaScript</a>, <a title="without JavaScript" href="http://www.webpagetest.org/result/120111_0P_2TW4Q/">without JavaScript</a>.) It&#8217;s not a perfect analysis: Some script URLs don&#8217;t contain &#8220;.js&#8221; and inline script blocks are still executed. I think this is a good approximation and I hope to do further experiments to corroborate this finding.</p>
<p><center><img class="alignnone" title="Top 100 sites with and without JS" src="http://stevesouders.com/images/withoutjs.png" alt="" width="460" height="291" /></center></p>
<h2>Async Execution Order &amp; Onload</h2>
<p>The other new infobyte has to do with the <code style="font-size: 1.1em;">async=true</code> line from the GA async snippet. The purpose of this line is to cause the <code>ga.js</code> script to not block other async scripts from being executed. It turns out that some browsers preserve the execution order of scripts loaded using the insertBefore technique, which is the technique used in the GA snippet:</p>
<div class="codesample" style="font-family: monospace;">var ga = document.createElement(‘script’);<br />
ga.type = ‘text/javascript’;<br />
ga.async = true;<br />
ga.src = (‘https:’ == document.location.protocol ? ‘https://ssl’ : ‘http://www’) + ‘.google-analytics.com/ga.js’;<br />
var s = document.getElementsByTagName(‘script’)[0];<br />
s.parentNode.insertBefore(ga, s);</div>
<p>Preserving execution order of async scripts makes the page slower. If the first async script takes a long time to download, all the other async scripts are blocked from executing, even if they download sooner. Executing async scripts immediately as they&#8217;re downloaded results in a faster page load time. I knew old versions of Firefox had this issue, and setting <code>async=true</code> fixed the problem. But I wanted to see if any other browsers also preserved execution order of async scripts loaded this way, and whether setting <code>async=true</code> worked.</p>
<p>To answer these questions I created a <a href="http://www.browserscope.org/user/tests/howto">Browserscope user test</a> called <a href="http://stevesouders.com/tests/jsorder.php">Async Script Execution Order</a>. I tweeted the test URL and got 348 results from 60+ different browsers. (Thanks to all the people that ran the test! I still need results from more mobile browsers so please run <a href="http://stevesouders.com/tests/jsorder.php">the test</a> if you have a browser that&#8217;s not covered.) Here&#8217;s a snapshot of <a href="http://www.browserscope.org/user/tests/table/agt1YS1wcm9maWxlcnINCxIEVGVzdBjrq90MDA?v=3&amp;layout=simple&amp;highlight=1">the results</a>:</p>
<div style="margin-bottom: 1em; text-align: center;"><a href="http://www.browserscope.org/user/tests/table/agt1YS1wcm9maWxlcnINCxIEVGVzdBjrq90MDA?v=2&amp;layout=simple&amp;highlight=1"><img class="alignnone" title="Execution order results" src="http://stevesouders.com/images/jsorder.png" alt="" width="460" height="576" /></a></div>
<p>The second column shows the results of loading two async scripts with the insertBefore pattern AND setting <code>async=true</code>. The third column shows the results if <code>async</code> is NOT set to <code>true</code>. Green means the scripts execute immediately (good) and red indicates that execution order is preserved (bad).</p>
<p>The results show that Firefox 3.6, OmniWeb 622, and all versions of Opera preserve execution order. Setting <code>async=true</code> successfully makes the async scripts execute immediately in Firefox 3.6 and OmniWeb 622, but not in Opera. Although this fix only applies to a few browsers, its small cost makes it worthwhile. Also, if we get results for more mobile browsers I would expect to find a few more places where the fix is necessary.</p>
<p>I also tested whether these insertBefore-style async scripts block the onload event. The results, shown in the fourth column, are mixed if we include older browsers, but we see that newer browsers generally block the onload event when loading these async scripts &#8211; this is true in Android, Chrome, Firefox, iOS, Opera, Safari, and IE 10. This is useful to know if you wonder why you&#8217;re still seeing long page load times even after adopting async script loading. It also means that code in your onload handler can&#8217;t reliably assume async scripts are loaded because of the many browsers out there that do <em>not</em> block the onload event, including IE 6-9.</p>
<p>And a final shout out to the awesomeness of the Open Source community that makes tools like <a href="http://webpagetest.org/">WebPagetest</a> and <a href="http://www.browserscope.org/">Browserscope</a> available &#8211; thanks <a href="https://twitter.com/#!/patmeenan">Pat</a> and <a href="https://twitter.com/#!/elsigh">Lindsey</a>!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.stevesouders.com/blog/2012/01/13/javascript-performance/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>Silk, iPad, Galaxy comparison</title>
		<link>http://www.stevesouders.com/blog/2011/12/01/silk-ipad-galaxy-comparison/</link>
		<comments>http://www.stevesouders.com/blog/2011/12/01/silk-ipad-galaxy-comparison/#comments</comments>
		<pubDate>Thu, 01 Dec 2011 17:51:58 +0000</pubDate>
		<dc:creator>Steve Souders</dc:creator>
				<category><![CDATA[mobile]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Loadtimer]]></category>
		<category><![CDATA[silk]]></category>
		<category><![CDATA[tablets]]></category>

		<guid isPermaLink="false">http://www.stevesouders.com/blog/?p=2333</guid>
		<description><![CDATA[In my previous blog post I announced Loadtimer &#8211; a mobile test harness for measuring page load times. I was motivated to create Loadtimer because recent reviews of the Kindle Fire lacked the quantified data and reliable test procedures needed to compare browser performance. Most performance evaluations of Silk that have come out since its [...]]]></description>
			<content:encoded><![CDATA[<p>In my <a href="http://www.stevesouders.com/blog/2011/12/01/loadtimer-a-mobile-test-harness/">previous blog post</a> I announced <a href="http://loadtimer.org/">Loadtimer</a> &#8211; a mobile test harness for measuring page load times. I was motivated to create Loadtimer because <a href="http://www.nytimes.com/2011/11/14/technology/personaltech/the-fire-aside-amazons-lower-priced-kindles-also-shine.html">recent</a> <a href="http://www.suntimes.com/technology/ihnatko/8816567-452/review-kindle-fire-is-no-ipad-killer-but-it-is-a-killer-device.html">reviews</a> <a href="http://www.theverge.com/2011/11/14/2560084/kindle-fire-review">of</a> <a href="http://www.engadget.com/2011/11/14/amazon-kindle-fire-review/">the</a> <a href="http://www.anandtech.com/show/5139/amazons-silk-browser-tested-less-bandwidth-consumed-but-slower-performance">Kindle</a> <a href="http://blog.yottaa.com/2011/11/kindle-fire-ipad-iphone-andriod-who-delivers-fast-web-experience-yottaa-friday-web-speed-race">Fire</a> lacked the quantified data and reliable test procedures needed to compare browser performance.</p>
<p>Most performance evaluations of Silk that have come out since its launch have two conclusions:</p>
<ol>
<li>Silk is faster when acceleration is turned off.</li>
<li>Silk is slow compared to other tablets.</li>
</ol>
<p>Let&#8217;s poke at those more rigorously using Loadtimer.</p>
<h3>Test Description</h3>
<p>In this test I&#8217;m going to compare the following tablets: Kindle Fire (with acceleration on and off), iPad 1, iPad 2, Galaxy 7.0, and Galaxy 10.1.</p>
<p>The test is based on how long it takes for web pages to load on each device. I picked 11 URLs that are top US websites:</p>
<ul>
<li><a href="http://www.yahoo.com/">http://www.yahoo.com/</a></li>
<li><a href="http://www.amazon.com/">http://www.amazon.com/</a></li>
<li><a href="http://en.wikipedia.org/wiki/Flowers">http://en.wikipedia.org/wiki/Flowers</a></li>
<li><a href="http://www.craigslist.com/">http://www.craigslist.com/</a></li>
<li><a href="http://www.ebay.com/">http://www.ebay.com/</a></li>
<li><a href="http://www.linkedin.com/">http://www.linkedin.com/</a></li>
<li><a href="http://www.bing.com/search?q=flowers">http://www.bing.com/search?q=flowers</a></li>
<li><a href="http://www.msn.com/">http://www.msn.com/</a></li>
<li><a href="http://www.engadget.com/">http://www.engadget.com/</a></li>
<li><a href="http://www.cnn.com/">http://www.cnn.com/</a></li>
<li><a href="http://www.reddit.com/">http://www.reddit.com/</a></li>
</ul>
<p>Some popular choices (<a href="http://www.google.com/">Google</a>, <a href="http://www.youtube.com/">YouTube</a>, and <a href="http://www.twitter.com/">Twitter</a>) weren&#8217;t selected because they have framebusting code and so don&#8217;t work in Loadtimer&#8217;s iframe-based test harness.</p>
<p>The set of 11 URLs were loaded 9 times on each device. The set of URLs was randomized for each run. All the tests were conducted on my home wifi over a Comcast cable modem. (Check out this <a href="http://stevesouders.com/images/testlab.jpg">photo of my test setup</a>.) All the tests were done at the same time of day over a 3 hour period. I did one test at a time to avoid bandwidth contention, and rotated through the devices doing one run at a time. I cleared the cache between each run.</p>
<h3>Apples and Oranges</h3>
<p>The median page load time for each URL on each device is shown in the <a href="http://loadtimer.org/results.php">Loadtimer Results page</a>. It&#8217;s a bit complicated to digest. The fastest load time is shown in green and the slowest is red &#8211; that&#8217;s easy. The main complication is that not every device got the same version of a given URL. Cells in the table that are shaded with a gray background were cases where the device received a mobile version of the URL. Typically (but not always) the mobile version is lighter than the desktop version (fewer requests, fewer bytes, less JavaScript, etc.) so it&#8217;s not valid to do a heads up comparison of page load times between desktop and mobile versions.</p>
<p>Out of 11 URLs, the Galaxy 7.0 received 6 that were mobile versions. The Galaxy 10.1 and Silk each received 2 mobile versions, and the iPads each had only one mobile version across the 11 URLs.</p>
<p>In order to gauge the difference between the desktop and mobile versions, the <a href="http://loadtimer.org/results.php">results table</a> shows the number of resources in each page. eBay, for example, had 64 resources in the desktop version, but only 18-22 in the mobile version. Not surprisingly, the three tablets that received the lighter mobile version had the fastest page load times. (If a mobile version was faster than the fastest desktop version, I show it in non-bolded green with a gray background.)</p>
<p>This demonstrates the importance of looking at the context of what&#8217;s being tested. In the comparisons below we&#8217;ll make sure to keep the desktop vs mobile issue in mind.</p>
<h3>Silk vs Silk</h3>
<p>Let&#8217;s start making some comparisons. The <a href="http://loadtimer.org/results.php">results table</a> is complicated when all 6 rows are viewed. The checkboxes are useful for making more focused comparisons. The <a href="http://loadtimer.org/results.php?b_5=Silk+%28accel+off%29+1.1.0&amp;b_6=Silk+%28accel+on%29+1.1.0&amp;comparesel=Compare+Selected&amp;data=blog">Silk (accel off) and Silk (accel on) results</a> show that indeed Silk performed better with acceleration turned off for every URL. This is surprising, but there are some things to note.</p>
<p><a href="http://loadtimer.org/results.php?b_5=Silk+%28accel+off%29+1&#038;b_6=Silk+%28accel+on%29+1&#038;comparesel=Compare+Selected&#038;data=blog"><img class="alignnone" src="http://stevesouders.com/images/silk-vs-silk.png" alt="" width="600" /></a></p>
<p>First, this is the first version of Silk. Jon Jenkins, Director of Software Development for Silk, spoke at <a href="http://velocityconf.com/velocityeu/">Velocity Europe</a> a few weeks back. In his <a href="http://velocityconf.com/velocityeu/public/schedule/detail/21891">presentation</a> he shows different places where the <em>split</em> in Silk&#8217;s split architecture could happen (slides 26-28). He also talked about the various types of optimizations that are part of the acceleration. Although he didn&#8217;t give specifics, it&#8217;s unlikely that all of those architectural pieces and performance optimizations have been deployed in this first version of Silk. The test results show that some of the obvious optimizations, such as concatenating scripts, aren&#8217;t happening when acceleration is on. I expect we&#8217;ll see more optimizations rolled out during the Silk release cycle, just as we do for other browsers.</p>
<p>A smaller but still important issue is that although the browser cache was cleared between tests, the DNS cache wasn&#8217;t cleared. When acceleration is on there&#8217;s only one DNS lookup needed &#8211; the one to Amazon&#8217;s server. When acceleration is off Silk has to do a DNS lookup for every unique domain &#8211; an average of <a href="http://httparchive.org/trends.php#numDomains">13 domains per page</a>. Having all of those DNS lookups cached gives an unfair advantage to the &#8220;acceleration off&#8221; page load times.</p>
<p>I&#8217;m still optimistic about the performance gains we&#8217;ll see as Silk&#8217;s split architecture matures, but for the remainder of this comparison we&#8217;ll use Silk with acceleration off since that performed best.</p>
<h3>Silk vs iPad</h3>
<p>I had both an iPad 1 and iPad 2 at my disposal so included both in the study. The iPad 1 was the slowest across all 11 URLs so I restricted the comparison to Silk (accel off) and iPad 2.</p>
<p><a href="http://loadtimer.org/results.php?b_4=iPad+2+5&#038;b_5=Silk+%28accel+off%29+1&#038;comparesel=Compare+Selected&#038;data=blog"><img class="alignnone" src="http://stevesouders.com/images/silk-vs-ipad.png" alt="" width="600" /></a></p>
<p>The results are mixed with iPad 2 being faster for most but not all URLs. The iPad 2 is fastest in 7 URLs. Silk is fastest in 3 URLs. One URL (eBay) is apples and oranges since Silk gets a mobile version of the site (18 resources compared to 64 resources for the desktop version).</p>
<h3>Silk vs Galaxy</h3>
<p>Comparing the Galaxy 7.0 to any other tablet is not fair since Galaxy 7.0 receives a lighter mobile version in 6 of 11 URLs. The Galaxy 7.0 has the slowest page load time in 3 of the 4 URLs where it, Galaxy 10.1, and Silk all receive the desktop version. Since it&#8217;s slower head-to-head and has mobile versions in the other URLs, I&#8217;ll focus on comparing Silk to the Galaxy 10.1.</p>
<p><a href="http://loadtimer.org/results.php?b_1=Galaxy+10&#038;b_5=Silk+%28accel+off%29+1&#038;comparesel=Compare+Selected&#038;data=blog"><img class="alignnone" src="http://stevesouders.com/images/silk-vs-galaxy.png" alt="" width="600" /></a></p>
<p>Silk has the fastest page load time in 7 URLs. The Galaxy 10.1 is faster in 3 URLs. One URL is mixed as Silk gets a mobile version (18 resources) while the Galaxy 10.1 gets a desktop version (64 resources).</p>
<h3> Takeaways</h3>
<p>These results show that, as strange as it might sound, Silk appears to be faster when acceleration is turned off. Am I going to turn off acceleration on my Kindle Fire? No. I don&#8217;t want to miss out on the next wave of performance optimizations in Silk. The browser is sound. It holds its own compared to other tablet browsers. Once the acceleration gets sorted out I expect it&#8217;ll do even better.</p>
<p>More importantly, it&#8217;s nice to have some real data and to have <a href="http://loadtimer.org/">Loadtimer</a> to help with future comparisons. Doing these comparisons to see which browser/tablet/phone is fastest makes for entertaining reading and heated competition. But all of us should expect more scientific rigor in the reviews we read, and push authors and ourselves to build and use better tools for measuring performance. I hope <a href="http://loadtimer.org/">Loadtimer</a> is useful. Loadtimer plus <a href="http://calendar.perfplanet.com/2010/mobile-performance-analysis-using-pcapperf/">pcapperf</a> and the <a href="http://stevesouders.com/mobileperf/mobileperfbkm.php">Mobile Perf bookmarklet</a> are the start of a mobile performance toolkit. Between the three of them I&#8217;m able to do most of what I need for analyzing mobile performance. It&#8217;s still a little clunky, but just as it happened in the desktop world we&#8217;ll see better tools with increasingly powerful features across more platforms as the industry matures. It&#8217;s still early days.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.stevesouders.com/blog/2011/12/01/silk-ipad-galaxy-comparison/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Loadtimer: a mobile test harness</title>
		<link>http://www.stevesouders.com/blog/2011/12/01/loadtimer-a-mobile-test-harness/</link>
		<comments>http://www.stevesouders.com/blog/2011/12/01/loadtimer-a-mobile-test-harness/#comments</comments>
		<pubDate>Thu, 01 Dec 2011 09:35:19 +0000</pubDate>
		<dc:creator>Steve Souders</dc:creator>
				<category><![CDATA[mobile]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[iframe]]></category>
		<category><![CDATA[Loadtimer]]></category>

		<guid isPermaLink="false">http://www.stevesouders.com/blog/?p=2339</guid>
		<description><![CDATA[Measuring mobile performance is hard When Amazon announced their Silk browser I got excited reading about the &#8220;split architecture&#8221;. I&#8217;m not big on ereaders but I pre-ordered my Kindle Fire that day. It arrived a week or two ago. I&#8217;ve been playing with it trying to find a scientific way to measure page load times [...]]]></description>
			<content:encoded><![CDATA[<h3>Measuring mobile performance is hard</h3>
<p>When Amazon <a href="http://amazonsilk.wordpress.com/">announced</a> their Silk browser I got excited reading about the &#8220;split architecture&#8221;. I&#8217;m not big on ereaders but I pre-ordered my Kindle Fire that day. It arrived a week or two ago. I&#8217;ve been playing with it trying to find a scientific way to measure page load times for various websites. It&#8217;s not easy.</p>
<ul>
<li>Since it&#8217;s a new browser and runs on a tablet we don&#8217;t have plugins like <a href="http://getfirebug.com/">Firebug</a>.</li>
<li>It doesn&#8217;t (yet) support the <a href="http://w3c-test.org/webperf/specs/NavigationTiming/">Navigation Timing spec</a>, so even though I can inspect pages using Firebug Lite (via the <a href="http://stevesouders.com/mobileperf/mobileperfbkm.php">Mobile Perf bookmarklet</a>) and <a href="http://phonegap.github.com/weinre/">Weinre</a> (I haven&#8217;t tried it but I assume it works), there&#8217;s no page load time value to extract.</li>
<li>Connecting my Fire to a wifi hotspot on my laptop running tcpdump (the technique evangelized by <a href="http://calendar.perfplanet.com/2010/mobile-performance-analysis-using-pcapperf/">pcapperf</a>) doesn&#8217;t work in accelerated mode because Silk uses SPDY over SSL. This technique works when acceleration is turned off, but I want to see the performance optimizations.</li>
</ul>
<p>While I was poking at this problem <a href="http://www.nytimes.com/2011/11/14/technology/personaltech/the-fire-aside-amazons-lower-priced-kindles-also-shine.html">a</a> <a href="http://www.suntimes.com/technology/ihnatko/8816567-452/review-kindle-fire-is-no-ipad-killer-but-it-is-a-killer-device.html">bunch</a> <a href="http://www.theverge.com/2011/11/14/2560084/kindle-fire-review">of</a> <a href="http://www.engadget.com/2011/11/14/amazon-kindle-fire-review/">Kindle</a> <a href="http://www.anandtech.com/show/5139/amazons-silk-browser-tested-less-bandwidth-consumed-but-slower-performance">Fire</a> <a href="http://blog.yottaa.com/2011/11/kindle-fire-ipad-iphone-andriod-who-delivers-fast-web-experience-yottaa-friday-web-speed-race">reviews</a> came out. Most of them talked about the performance of Silk, but I was disappointed by the lack of scientific rigor in the testing. Instead of data there were subjective statements like &#8220;the iPad took about half as long [compared to Silk]&#8221; and &#8220;the Fire routinely got beat in rendering pages but often not by much&#8221;. Most of the articles did not include a description of the test procedures. I contacted one of the authors who confided that they used a stopwatch to measure page load times.</p>
<p>If we&#8217;re going to critique Silk and compare its performance to other browsers we need reproducible, unbiased techniques for testing performance. Using a stopwatch or loading pages side-by-side and doing a visual comparison to determine which is faster are not reliable methods for measuring performance. We need better tools.</p>
<h3>Introducing Loadtimer</h3>
<p>Anyone doing mobile web development knows that dev tools for mobile are lacking. Firebug came out in 2006. We&#8217;re getting close to having that kind of functionality in mobile browsers using remote debuggers, but it&#8217;s pretty safe to say the state of mobile dev tools is 3-5 years behind desktop tools. It might not be sexy, but there&#8217;s a lot to be gained from taking tools and techniques that worked on the desktop and moving them to mobile.</p>
<p>In that vein I&#8217;ve been working the last few days to build an iframe-based test harness similar to one I built back in 2003. I call it <a href="http://loadtimer.org/">Loadtimer</a>. (I was shocked to see this domain was available &#8211; that&#8217;s a first.) Here&#8217;s a screenshot:</p>
<p style="text-align: center;"><a href="http://loadtimer.org/screenshot.png"><img class="alignnone" style="border: 1px solid #000;" title="Loadtimer UI" src="http://loadtimer.org/screenshot.png" alt="" width="490" height="349" /></a></p>
<p>The way it works is straightforward:</p>
<ul>
<li>It&#8217;s preloaded with a list of popular URLs. The list of URLs can be modified.</li>
<li>The URLs are loaded one-at-a-time into the iframe lower in the page.</li>
<li>The iframe&#8217;s onload time is measured and displayed on the right next to each URL.</li>
<li>If you check &#8220;record load times&#8221; the page load time is beaconed to the specified URL. The beacon URL defaults to point to loadtimer.org, but you can modify it if, for example, you&#8217;re testing some private pages and want the results to go to your own server.</li>
<li>You can&#8217;t test websites that have &#8220;framebusting&#8221; code that prevents them from being loaded in an iframe, such as <a href="http://www.google.com/">Google</a>, <a href="http://www.youtube.com/">YouTube</a>, <a href="http://www.twitter.com/">Twitter</a>, and <a href="http://www.nytimes.com/">NYTimes</a>.</li>
</ul>
<p>There are some subtle optimizations worth noting:</p>
<ul>
<li>You should clear the cache between each run (unless you explicitly want to test the primed cache experience). There&#8217;s no way for the test harness to clear the cache, but it does have a check that helps remind you to clear the cache. (It loads a script that is known to take 3 seconds to load &#8211; if it takes less than 3 seconds it means the cache wasn&#8217;t cleared.)</li>
<li>It&#8217;s possible that URL 1&#8242;s unload time could make URL 2&#8242;s onload time be longer than it actually should be. To avoid this <code>about:blank</code> is loaded between each URL.</li>
<li>The order of the preset URLs is randomized to mitigate biases across URLs, for example, where URL 1 loads resources used by URL 2.</li>
</ul>
<p>Two biases that aren&#8217;t addressed by Loadtimer:</p>
<ul>
<li>DNS resolutions aren&#8217;t cleared. I don&#8217;t think there&#8217;s a way to do this on mobile devices short of power cycling. This could be a significant issue when comparing Silk with acceleration on and off. When acceleration is on there&#8217;s only one DNS lookup, whereas when acceleration is off there&#8217;s a DNS lookup for each hostname in the page (<a href="http://httparchive.org/trends.php#numDomains">13 domains per page</a> on average). Having the DNS resolutions cached gives an advantage to acceleration being off.</li>
<li>Favicons aren&#8217;t loaded for websites in iframes. This probably has a negligible impact on page load times.</li>
</ul>
<h3> Have at it</h3>
<p>The nice thing about the <a href="http://loadtimer.org/">Loadtimer</a> test harness is that it&#8217;s web-based &#8211; nothing to install. This ensures it&#8217;ll work on all mobile phones and tablets that support JavaScript. The <a href="http://code.google.com/p/loadtimer/">code</a> is open source. There&#8217;s a <a href="http://groups.google.com/group/loadtimer/topics">forum</a> for questions and discussions.</p>
<p>There&#8217;s also a <a href="http://loadtimer.org/results.php">results page</a>. If you select the &#8220;record load times&#8221; checkbox you&#8217;ll be helping out by contributing to the crowdsourced data that&#8217;s being gathered. Getting back to what started all of this, I&#8217;ve also been using Loadtimer the last few days to compare the performance of Silk to other tablets. Those results are the topic of my next blog post &#8211; see you there.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.stevesouders.com/blog/2011/12/01/loadtimer-a-mobile-test-harness/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Add your site &amp; custom fonts</title>
		<link>http://www.stevesouders.com/blog/2011/11/17/add-your-site-custom-fonts/</link>
		<comments>http://www.stevesouders.com/blog/2011/11/17/add-your-site-custom-fonts/#comments</comments>
		<pubDate>Fri, 18 Nov 2011 03:45:06 +0000</pubDate>
		<dc:creator>Steve Souders</dc:creator>
				<category><![CDATA[Conferences]]></category>
		<category><![CDATA[HTTP Archive]]></category>
		<category><![CDATA[Performance]]></category>

		<guid isPermaLink="false">http://www.stevesouders.com/blog/?p=2323</guid>
		<description><![CDATA[The Nov 15 2011 crawls for the HTTP Archive and HTTP Archive Mobile are done. Two new things were added. Add your site Our goal is to crawl the world&#8217;s top 1,000,000 URLs. This month we doubled the number of URLs from 17K to 35K. We&#8217;re still a ways away but making progress. But what [...]]]></description>
			<content:encoded><![CDATA[<p>The Nov 15 2011 crawls for the <a href="http://httparchive.org/">HTTP Archive</a> and <a href="http://mobile.httparchive.org/">HTTP Archive Mobile</a> are done. Two new things were added.</p>
<h3>Add your site</h3>
<p>Our goal is to crawl the world&#8217;s top 1,000,000 URLs. This month we doubled the number of URLs from 17K to 35K. We&#8217;re still a ways away but making progress. But what if you&#8217;d like your website to be in the HTTP Archive but it isn&#8217;t in the top 1M?</p>
<p>Now you can <a href="http://httparchive.org/addsite.php">add your site</a> to the HTTP Archive. If it&#8217;s already in the list we&#8217;ll tell you and point you to any data that&#8217;s been gathered so far. If it&#8217;s not in the list we&#8217;ll queue it up for the next crawl. We moderate all additions to make sure the URL is valid. We also have a limit of 1 URL per website. We strive to crawl a site&#8217;s main URL (e.g., http://stevesouders.com/) but not all the subpages within a site (http://stevesouders.com/about.php, http://www.example.com/videos.php, etc.).</p>
<h3>Custom Fonts</h3>
<p>I&#8217;ve been thinking more about custom fonts after <a href="http://typekit.com/">Typekit</a>&#8216;s acquisition by Adobe and seeing Jeff Veen at <a href="http://velocityconf.com/velocityeu/">Velocity Europe</a>. (Make sure to watch the <a href="http://www.youtube.com/watch?v=v2UwvN6zusg&amp;list=PLEF30FFC877957631&amp;index=10&amp;feature=plpp_video">video of Jeff&#8217;s talk</a> &#8211; it&#8217;s an amazing presentation with a humorous start.) So this week I added a chart to track the adoption of custom fonts:</p>
<p><a href="http://httparchive.org/trends.php?s=intersection#perFonts"><img class="alignnone" title="Adoption of Custom Fonts" src="http://stevesouders.com/images/ha-custom-fonts.png" alt="" width="500" height="250" /></a></p>
<p>Typekit is clearly on to something &#8211; the use of custom fonts has tripled in one year. I <a href="http://www.stevesouders.com/blog/2009/10/13/font-face-and-performance/">warn</a> <a href="http://www.stevesouders.com/blog/2010/06/01/frontend-spof/">against</a> using @font-face for performance reasons, but performance isn&#8217;t all that matters. (Gasp!) Custom fonts obviously have aesthetic benefits that are attractive to website owners.</p>
<p>Fortunately, Typekit has several performance optimizations in how they load fonts. They combine all the fonts in a single stylesheet for browsers that support data: URIs. The fonts are served over a CDN. The font&#8217;s are only cacheable for 5 minutes which hurts repeat visits, but I believe they&#8217;re working on longer cache times.</p>
<p>For truly fast and robust font loading we need to lean on browser developers to implement better caching for fonts and better timeout choices during rendering. I&#8217;ll be talking about this during <a href="http://qconsf.com/sf2011/presentation/High+Performance+HTML5">my High Performance HTML5 session at QCon</a> on Friday.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.stevesouders.com/blog/2011/11/17/add-your-site-custom-fonts/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>HTTP Archive growing</title>
		<link>http://www.stevesouders.com/blog/2011/11/03/http-archive-growing/</link>
		<comments>http://www.stevesouders.com/blog/2011/11/03/http-archive-growing/#comments</comments>
		<pubDate>Thu, 03 Nov 2011 21:11:36 +0000</pubDate>
		<dc:creator>Steve Souders</dc:creator>
				<category><![CDATA[HTTP Archive]]></category>

		<guid isPermaLink="false">http://www.stevesouders.com/blog/?p=2294</guid>
		<description><![CDATA[Today the number of URLs analyzed was doubled in both the HTTP Archive (from 17K to 34K URLs) and in the HTTP Archive Mobile (from 1K to 2K URLs). This is a small step toward our goal of 1 million URLs, but it validates numerous code changes that landed recently: 22: update URL lists &#8211; [...]]]></description>
			<content:encoded><![CDATA[<p>Today the number of URLs analyzed was <em>doubled</em> in both the <a href="http://httparchive.org/">HTTP Archive</a> (from 17K to 34K URLs) and in the <a href="http://mobile.httparchive.org/">HTTP Archive Mobile</a> (from 1K to 2K URLs).</p>
<p><center><nobr><a style="margin-right: 2em;" href="http://httparchive.org/trends.php#numurls"><img title="HTTP Archive Number of URLs Analyzed" src="http://stevesouders.com/images/ha-urls-analyzed.png" alt="" width="230" /></a><a href="http://mobile.httparchive.org/trends.php#numurls"><img title="HTTP Archive Mobile Number of URLs Analyzed" src="http://stevesouders.com/images/ham-urls-analyzed.png" alt="" width="230" /></a></nobr></center></p>
<p>
This is a small step toward our goal of 1 million URLs, but it validates numerous <a href="http://code.google.com/p/httparchive/issues/list?can=1&amp;q=status:Fixed&amp;sort=-modified&amp;colspec=ID%20Type%20Status%20Priority%20Owner%20Component%20Summary%20Modified">code changes that landed recently</a>:</p>
<ul>
<li><a href="http://code.google.com/p/httparchive/issues/detail?id=22">22: update URL lists</a> &#8211; Previously the list of URLs to crawl was manually created (by me) from multiple other lists (Alexa, Quantcast, Fortune 500, etc.). Because it was manually created it wasn&#8217;t updated frequently. Now the list is based on the <a href="http://www.alexa.com/topsites">Alexa Top 1,000,000 Sites</a> and is updated every crawl.</li>
<li><a href="http://code.google.com/p/httparchive/issues/detail?id=243">243: handle non-ranked URLs</a> &#8211; Some of the URLs crawled up until now are NOT in the Alexa Top 1M. In order to support looking at long term trends (by selecting &#8220;<a href="http://httparchive.org/trends.php?s=intersection">intersection</a>&#8220;) I wanted to continue crawling these outliers. So the list of URLs that is crawled supports crawling non-ranked websites. This will allow many other nice features that you&#8217;ll hear about next week.</li>
<li><a href="http://code.google.com/p/httparchive/issues/detail?id=242">242: rewrite batch_process.php</a> &#8211; There&#8217;s a bunch of code for doing the crawl that needed to be made more efficient as we increase two orders of magnitude.</li>
<li><a href="http://code.google.com/p/httparchive/issues/detail?id=68">68: cache aggregate stats for trends.php</a> &#8211; Again, in order to deal with a larger number of URLs and still generate charts quickly, I introduced a caching layer for the aggregate stats.</li>
<li><a href="http://code.google.com/p/httparchive/issues/detail?id=196">#196: Publish a mysql schema dump</a> &#8211; Exploring the data is now easier. Instead of having to setup an entire instance of the code, you simply create the tables based on the <a href="http://mobile.httparchive.org/downloads/httparchive_schema.sql">schema dump</a> and <a href="http://httparchive.org/downloads.php">download data</a> that is of interest.</li>
</ul>
<p>With these and other changes behind us, we&#8217;ll continue to increase the number of URLs to reach our goal. There are still some big tasks to tackle including changing the DB schema, increasing the capacity on mobile with more devices or switching to an emulator, and combining these two sites into a single site for easier comparison of desktop &amp; mobile data.</p>
<p>No blog post about HTTP Archive would be complete without some observations. As mentioned earlier, whenever looking at long term trends I choose the <a href="http://httparchive.org/trends.php?s=intersection">intersection</a> &#8211; which means the exact same URLs are included in every data point.</p>
<p>The main trend I&#8217;ve been noticing is how the size of resources is growing much faster than the number of resources. This growth is most evident in scripts and images. It&#8217;s no surprise &#8211; the Web is getting bigger. But now we can see where that&#8217;s happening and explore solutions.</p>
<p><center><nobr><a style="margin-right: 2em;" href="http://httparchive.org/trends.php#bytesJS&amp;reqJS"><img title="JS Size and Requests" src="http://stevesouders.com/images/ha-js-xfer.png" alt="" width="230" /></a><a href="http://httparchive.org/trends.php#bytesImg&amp;reqImg"><img title="Image Size and Requests" src="http://stevesouders.com/images/ha-img-xfer.png" alt="" width="230" /></a></nobr></center></p>
<p>
I also wanted to shout out to <a href="http://blog.patrickmeenan.com/">Pat Meenan</a> and <a href="https://twitter.com/#!/guypod">Guy (&#8220;Guypo&#8221;) Podjarny</a>. Pat works at <a href="http://www.google.com/">Google</a> and is the creator of <a href="http://webpagetest.org/">WebPagetest</a>, which is the foundation for the HTTP Archive (Mobile). Guypo works at <a href="http://www.blaze.io/">Blaze</a> and provides additional infrastructure and devices for all the mobile testing. In addition, there are a growing number of <a href="http://httparchive.org/about.php#who">contributors</a> to the open source project. And none of this would be happening without support from our sponsors: <a title="Google" href="http://www.google.com/">Google</a>, <a title="Mozilla" href="http://www.mozilla.org/firefox">Mozilla</a>, <a title="New Relic" href="http://www.newrelic.com/">New Relic</a>, <a title="O'Reilly Media" href="http://oreilly.com/">O’Reilly Media</a>, <a href="http://www.etsy.com/">Etsy</a>, <a title="Strangeloop Networks" href="http://www.strangeloopnetworks.com/">Strangeloop</a>, and <a title="dynaTrace Software" href="http://www.dynatrace.com/">dynaTrace Software</a>.</p>
<p>Watch for a fun announcement next week.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.stevesouders.com/blog/2011/11/03/http-archive-growing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Velocity Europe &#8211; High Performance Berlin!</title>
		<link>http://www.stevesouders.com/blog/2011/10/24/velocity-europe-high-performance-berlin/</link>
		<comments>http://www.stevesouders.com/blog/2011/10/24/velocity-europe-high-performance-berlin/#comments</comments>
		<pubDate>Tue, 25 Oct 2011 05:32:47 +0000</pubDate>
		<dc:creator>Steve Souders</dc:creator>
				<category><![CDATA[Velocity]]></category>

		<guid isPermaLink="false">http://www.stevesouders.com/blog/?p=2279</guid>
		<description><![CDATA[Velocity Europe is less than two weeks away. It&#8217;s happening November 8-9 in Berlin at the Hotel Maritim ProArte. I&#8217;ve heard good things about the venue and am excited to get there and check it out. This event has been a long time coming. A handful of web performance and operations savants (including members of [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://velocityconf.com/velocityeu/">Velocity Europe</a> is less than two weeks away. It&#8217;s happening November 8-9 in Berlin at the <a href="http://velocityconf.com/velocityeu/public/content/hotel">Hotel Maritim ProArte</a>. I&#8217;ve heard good things about the venue and am excited to get there and check it out.</p>
<p>This event has been a long time coming. A handful of web performance and operations savants (including members of the Program Committee) have been encouraging us for years to bring Velocity to Europe, and now it&#8217;s actually happening. And (drum roll please) the price is only EUR 600 (excl. VAT) if you use the 20% discount code <strong><code style="color: #cc0000; font-size: 1.2em;">veu11sts</code></strong>. (And don&#8217;t forget about the free <a href="http://velocityconf.com/velocity-oct2011">Velocity Online Conference</a> this week &#8211; see more below.)</p>
<p>The <a href="http://velocityconf.com/velocityeu/public/schedule/speakers">Velocity Europe speaker line-up</a> is exceptional. Some highlights include:</p>
<ul>
<li><a href="http://velocityconf.com/velocityeu/public/schedule/speaker/1784">Jon Jenkins</a> from Amazon.com is talking about their approach to the challenges of mobile browsing. Jon is the Director of Software Development for Amazon Silk. I&#8217;m looking forward to more details about Silk&#8217;s split architecture.</li>
<li><a href="http://velocityconf.com/velocityeu/public/schedule/speaker/23159">Tim Morrow</a> delivers the background for <a href="https://promotions.betfair.com/customer-commitment/">Betfair&#8217;s promise</a> to deliver a fast experience to their customers, and their progress on that promise.</li>
<li><a href="http://velocityconf.com/velocityeu/public/schedule/speaker/4103">Theo Schlossnagle</a> is a recognized leader at Velocity. He&#8217;s giving two talks on web operations careers and monitoring.</li>
<li><a href="http://velocityconf.com/velocityeu/public/schedule/speaker/53274">Estelle Weyl</a> joins Velocity for the first time talking about the nuances of mobile rendering performance. I learn something new everytime I hear Estelle speak, so am excited to welcome her to Velocity.</li>
<li><a href="http://velocityconf.com/velocityeu/public/schedule/speaker/112081">Ivo Teel</a> discusses the balance we all face between features and performance and how they&#8217;re handling that at Spil Games.</li>
<li><a href="http://velocityconf.com/velocityeu/public/schedule/speaker/41670">Jeff Veen</a> knows the importance of 3rd party performance and availability as the CEO of <a href="http://typekit.com/">Typekit</a>. Jeff&#8217;s an amazing, engaging speaker. Reading his <a title="Designing for Disaster" href="http://velocityconf.com/velocityeu/public/schedule/detail/21788">session description</a> gave me goosebumps with anticipation: <em>Jeff sat on a couch in the Typekit offices, staring out the window, and wondering if everything their company had been working towards was about to slip through their fingers&#8230;</em></li>
</ul>
<p>There&#8217;s much much more &#8211; <a href="http://velocityconf.com/velocityeu/public/schedule/detail/22652">lightning</a> <a href="http://velocityconf.com/velocityeu/public/schedule/detail/22654">demos</a>, <a title="Opera" href="http://velocityconf.com/velocityeu/public/schedule/detail/22183">browser</a> <a title="Chrome" href="http://velocityconf.com/velocityeu/public/schedule/detail/21763">vendor</a> <a title="Firefox" href="http://velocityconf.com/velocityeu/public/schedule/detail/21787">talks</a>, <a href="http://velocityconf.com/velocityeu/public/schedule/detail/22258">Allspaw on anticipating failure</a>, <a href="http://velocityconf.com/velocityeu/public/schedule/detail/21874">Mandelin on JavaScript performance</a> &#8211; I&#8217;ve got to stop here but please check out the <a title="Velocity schedule" href="http://velocityconf.com/velocityeu/public/schedule/grid">entire schedule</a>.</p>
<p>I want to give a shout out to the Velocity Europe Program Committee: <a href="http://www.jedi.be/">Patrick Debois</a>, <a href="http://velocityconf.com/velocityeu/public/schedule/speaker/79329">Aaron Peters</a>, <a href="http://velocityconf.com/velocityeu/public/schedule/speaker/107054">Schlomo Schapiro</a>, <a href="http://velocityconf.com/velocityeu/public/schedule/speaker/71702">Jeroen Tjepkema</a>, and <a href="http://soundcloud.com/sean">Sean Treadway</a>. They&#8217;ve participated in numerous video concalls (yay Google Hangouts!) to review proposals, build the program, and shape Velocity to be a European conference. And they might have one more card up their sleeve &#8211; more on that later.</p>
<p>You can get a <em>free</em> warm-up for Velocity Europe at the <a href="http://velocityconf.com/velocity-oct2011">Velocity Online Conference</a> this week. It&#8217;s Wednesday October 26 9-11:30am PDT. John Allspaw, Velocity co-chair, has rounded up four speakers to cover several hot topics including monitoring, global DNS, and making yourself even more awesome(!). It&#8217;s free, but <a title="Velocity OLC registration" href="https://event.on24.com/eventRegistration/EventLobbyServlet?target=registration.jsp&amp;eventid=367258&amp;sessionid=1&amp;key=05DE461FF7DA7A2A7E4E7FF82D690C59&amp;sourcepage=register">you have to register for Velocity OLC</a> if you want to get in on the conversation.</p>
<p>If you&#8217;re heading to Berlin you should also check out <a href="http://www.couchbase.com/couchconf-berlin">CounchConf Berlin</a> on Nov 7. NoSQL has great performance benefits and Couchbase is a good choice for many mobile apps. Use <strong><code style="color: #cc0000; font-size: 1.2em;">couchconf_discount </code></strong> for 10% off registration.</p>
<p>The last time I was in Berlin was for <a href="http://jsconf.eu/2009/about-jsconf-eu.html">JSConf.eu 2009</a>. The city had a high tech vibe and the crowd was extremely knowledgeable and enthusiastic. I&#8217;m excited to get back to Berlin for Velocity Europe and do the web performance and operations deep dives that are the core of Velocity. If you want to have a website that&#8217;s always fast and always up, Velocity Europe is the place to be. I hope to see you there.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.stevesouders.com/blog/2011/10/24/velocity-europe-high-performance-berlin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HTTP Archive: new code, new charts</title>
		<link>http://www.stevesouders.com/blog/2011/10/20/http-archive-new-code-new-charts/</link>
		<comments>http://www.stevesouders.com/blog/2011/10/20/http-archive-new-code-new-charts/#comments</comments>
		<pubDate>Thu, 20 Oct 2011 08:24:59 +0000</pubDate>
		<dc:creator>Steve Souders</dc:creator>
				<category><![CDATA[HTTP Archive]]></category>
		<category><![CDATA[Performance]]></category>

		<guid isPermaLink="false">http://www.stevesouders.com/blog/?p=2269</guid>
		<description><![CDATA[The HTTP Archive is a permanent record of web performance information started in October 2010. The world&#8217;s top 17,000 web pages are analyzed twice each month to collect information such as the number and size of HTTP requests, whether responses are cacheable, the percent of pages with errors, and the average Page Speed score. The [...]]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://httparchive.org/">HTTP Archive</a> is a permanent record of web performance information started in October 2010. The world&#8217;s top 17,000 web pages are analyzed twice each month to collect information such as the <a href="http://httparchive.org/trends.php#bytesTotal&amp;reqTotal">number and size of HTTP requests</a>, whether responses are <a href="http://httparchive.org/interesting.php#max-age">cacheable</a>, the percent of pages with <a href="http://httparchive.org/interesting.php#errors">errors</a>, and the average <a href="http://httparchive.org/trends.php#PageSpeed">Page Speed score</a>. The <a href="http://code.google.com/p/httparchive/source/browse">code</a> is open source and all the data is <a href="http://httparchive.org/downloads.php">downloadable</a>.</p>
<p>The next big step is to increase the number of URLs to 1 million. The biggest task to get to this point is improving the database schema and caching. This past week I made some significant code contributions around caching aggregate stats across all the web sites. Even with only 17K URLs the speed improvement for generating charts is noticeable.</p>
<p>The new stats cache allows me to aggregate more data than before, so I was able to add several trending charts. (The increases/decreases are Nov 15 2010 to Oct 15 2011.)</p>
<ul>
<li>percent of sites using <a href="http://httparchive.org/trends.php#perGlibs">Google Libraries API</a> &#8211; up 6%</li>
<li>percent of sites using <a href="http://httparchive.org/trends.php#perFlash">Flash</a> &#8211; down 2%</li>
<li>percent of responses with <a href="http://httparchive.org/trends.php#maxageNull">caching headers</a> &#8211; up 4%</li>
<li>percent of requests made using <a href="http://httparchive.org/trends.php#perHttps">HTTPS</a> &#8211; up 1%</li>
<li>percent of pages with one or more <a href="http://httparchive.org/trends.php#perErrors">errors</a> &#8211; down 2%</li>
<li>percent of pages with one or more <a href="http://httparchive.org/trends.php#perRedirects">redirects</a> &#8211; up 7%</li>
</ul>
<p>Most of the news is good from a performance perspective, except for the increase in redirects. Here&#8217;s the caching headers chart as an example:</p>
<p><a href="http://stevesouders.com/images/ha-trends-caching.png"><img class="alignnone" title="Requests with Caching Headers" src="http://stevesouders.com/images/ha-trends-caching.png" alt="" width="480" border="0" /></a></p>
<p>I dropped the following charts:</p>
<ul>
<li>popular JavaScript libraries &#8211; I created this chart using handcrafted regular expressions that attempted to find requests for popular frameworks such as jQuery and YUI. Those regexes are not always accurate and are hard to maintain. I recommend people use the <a href="http://trends.builtwith.com/javascript">JavaScript Usage Statistics</a> from BuiltWith for this information.</li>
<li>popular web servers &#8211; Again, BuiltWith&#8217;s <a href="http://trends.builtwith.com/Web-Server">Web Server Usage Statistics</a> is a better reference for this information.</li>
<li>sites with the most (JavaScript | CSS | Images | Flash) &#8211; These charts were interesting, but not that useful.</li>
<li>popular scripts &#8211; This was a list of the top 5 most referenced scripts based on a specific URL. The problem is that the same script can have a URL that varies based on hostnames, querystring parameters, etc.</li>
</ul>
<p>The new stats cache is a great step forward. I have a few more big coding sessions to finish but I hope to get enough done that we can start increasing the number of URLs in the next run or two. I&#8217;ll keep you posted.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.stevesouders.com/blog/2011/10/20/http-archive-new-code-new-charts/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>frontend SPOF survey</title>
		<link>http://www.stevesouders.com/blog/2011/10/13/frontend-spof-survery/</link>
		<comments>http://www.stevesouders.com/blog/2011/10/13/frontend-spof-survery/#comments</comments>
		<pubDate>Thu, 13 Oct 2011 16:10:31 +0000</pubDate>
		<dc:creator>Steve Souders</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[blackhole]]></category>
		<category><![CDATA[frontend SPOF]]></category>

		<guid isPermaLink="false">http://www.stevesouders.com/blog/?p=2247</guid>
		<description><![CDATA[Pat Meenan had a great blog post yesterday, Testing for Frontend SPOF. &#8220;SPOF&#8221; means single point of failure. I coined the term frontend SPOF to describe the all-too-likely situation where the HTML document returns successfully, but some other resource (a stylesheet, script, or font file) blocks the entire website from loading. This typically manifests itself [...]]]></description>
			<content:encoded><![CDATA[<p>Pat Meenan had a great blog post yesterday, <a href="http://blog.patrickmeenan.com/2011/10/testing-for-frontend-spof.html">Testing for Frontend SPOF</a>. &#8220;SPOF&#8221; means single point of failure. I coined the term <em>frontend SPOF</em> to describe the all-too-likely situation where the HTML document returns successfully, but some other resource (a stylesheet, script, or font file) blocks the entire website from loading. This typically manifests itself as a blank white screen that the user stares out for 20 seconds or longer.</p>
<p>Frontend SPOF happens most frequently with third party content. If the HTML document returns successfully, then all the resources from the main website are likely to return successfully, as well. Third party content, however, isn&#8217;t controlled by the main website and thus could be suffering an outage or overload while the main website is working fine. As a result, the uptime of a website is no greater than the availability of the third party resources it uses that are in a position to cause frontend SPOF.</p>
<p>In <a href="http://www.stevesouders.com/blog/2010/06/01/frontend-spof/">my blog post of the same name</a> I describe how Frontend SPOF happens and ways to avoid it, but I don&#8217;t provide a way for website owners to determine which third party resources may cause frontend SPOF. This is where Pat comes in. He&#8217;s created a public blackhole server: <code>blackhole.webpagetest.org</code> with the static IP address <code>72.66.115.13</code>. Pointing your third party resources to this blackhole and reloading the page tells you if those resources cause frontend SPOF. Since Pat is the creator of <a href="http://www.webpagetest.org/">WebPagetest.org</a>, he has integrated this into the scripting capabilities of that tool so website owners can load their website and determine if any third party resources cause frontend SPOF.</p>
<h2>/etc/hosts</h2>
<p>I took a different approach outlined by Pat: I added the following lines to my <code>/etc/hosts</code> file (your location may vary) mapping these third party hostnames to point to the blackhole server:</p>
<pre class="codesample" style="background: #FFF;">72.66.115.13 apis.google.com
72.66.115.13 www.google-analytics.com
72.66.115.13 connect.facebook.net
72.66.115.13 platform.twitter.com
72.66.115.13 s7.addthis.com
72.66.115.13 l.addthiscdn.com
72.66.115.13 cf.addthis.com
72.66.115.13 api-public.addthis.com
72.66.115.13 widget.quantcast.com
72.66.115.13 ak.quantcast.com
72.66.115.13 assets.omniture.com
72.66.115.13 www.omniture.com
72.66.115.13 scripts.omniture.com
72.66.115.13 b.voicefive.com
72.66.115.13 ar.voicefive.com
72.66.115.13 c.statcounter.com
72.66.115.13 www.statcounter.com
72.66.115.13 www-beta.statcounter.com
72.66.115.13 js.revsci.net</pre>
<p>After restarting my browser all requests to these hostnames will timeout. Pat&#8217;s blog post mentions 20 seconds for a timeout. He was running on Windows. I&#8217;m running on my Macbook where the timeout is <em>75 seconds</em>! Any website that references third party content on these hostnames in a way that produces frontend SPOF will be blank for 75 seconds &#8211; an easy failure to spot.</p>
<h2>survey says</h2>
<p>THE GOOD: At this point I started loading the <a href="http://www.alexa.com/topsites/countries/US">top 100 US websites</a>. I was pleasantly surprised. None of the top 20 websites suffered from frontend SPOF. There were several that loaded third party content from these hostnames, but they had safeguarded themselves:</p>
<ul>
<li><a href="http://www.msn.com/">MSN</a> makes a request to <code>ar.voicefive.com</code>, but does it asynchronously using a document.write technique.</li>
<li><a href="http://www.aol.com/">AOL</a> references <code>platform.twitter.com</code>, but puts the SCRIPT tag at the very bottom of the BODY so page rendering isn&#8217;t blocked.</li>
<li><a href="http://www.imdb.com/">IMDB</a> uses the <a href="http://code.google.com/apis/analytics/docs/tracking/asyncTracking.html">async version of Google Analytics</a>, and puts the <code>platform.twitter.com</code> widget in an iframe.</li>
<li><a href="http://www.livejournal.com/">LiveJournal</a> goes above and beyond by wrapping the Google +1 and Facebook widgets in a homegrown async script loader.</li>
</ul>
<p>THE BAD: Going through the top 100 I found five websites that had frontend SPOF:</p>
<ol>
<li><a href="http://www.cnet.com/">CNET</a> loads <code>http://platform.twitter.com/widgets.js</code> in the HEAD as a blocking script.</li>
<li><a href="http://www.stumbleupon.com/">StumbleUpon</a> loads <code>http://connect.facebook.net/en_US/all.js</code> at the top of BODY as a blocking script.</li>
<li><a href="http://www.nfl.com/">NFL</a> loads <code>http://connect.facebook.net/en_US/all.js</code> in the HEAD as a blocking script.</li>
<li><a href="http://www.hulu.com/">Hulu</a>, incredibly, loads Google Analytics in the HEAD as a blocking script. Please use the <a href="http://code.google.com/apis/analytics/docs/tracking/asyncTracking.html">async snippet</a>!</li>
<li><a href="http://www.expedia.com/">Expedia</a> loads <code>http://connect.facebook.net/en_US/all.js</code> as a blocking script in the middle of the page, so the right half of the page is blocked from rendering.</li>
</ol>
<p>These results, although better than I expected, are still alarming. Although I only found five websites with frontend SPOF, that&#8217;s 5% of the overall sample. The percentage will likely grow as the sample size grows because best practices are more widely adopted by the top sites. Also, my list of third party hostnames is a small subset of all widgets and analytics available on the Web. And remember, I didn&#8217;t even look at ads.</p>
<p>Is it really worth blocking your site&#8217;s entire page for a widget button or analytics beacon &#8211; especially when workarounds exist? If you&#8217;re one of the five sites that faltered above, do yourself and your users a favor and find a way to avoid frontend SPOF. And if you&#8217;re outside the top 100, test your site using Pat&#8217;s blackhole server by editing <code>/etc/hosts</code> or following <a title="blackhole scripting instructions" href="http://blog.patrickmeenan.com/2011/10/testing-for-frontend-spof.html">Pat&#8217;s instructions</a> for testing frontend SPOF on <a href="http://www.webpagetest.org/">WebPagetest.org</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.stevesouders.com/blog/2011/10/13/frontend-spof-survery/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Improving app cache</title>
		<link>http://www.stevesouders.com/blog/2011/10/03/improving-app-cache/</link>
		<comments>http://www.stevesouders.com/blog/2011/10/03/improving-app-cache/#comments</comments>
		<pubDate>Mon, 03 Oct 2011 19:42:53 +0000</pubDate>
		<dc:creator>Steve Souders</dc:creator>
				<category><![CDATA[mobile]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[app cache]]></category>
		<category><![CDATA[w3c]]></category>

		<guid isPermaLink="false">http://www.stevesouders.com/blog/?p=2173</guid>
		<description><![CDATA[I recently found out about the W3C Workshop on The Future of Off-line Web Applications on November 5 in Redwood City. I won&#8217;t be able to attend (I&#8217;ll be heading to Velocity Europe), but I feel like app cache needs improving so I summarized my thoughts and sent it to the workshop organizers. I also [...]]]></description>
			<content:encoded><![CDATA[<p>I recently found out about the <a href="http://www.w3.org/2011/web-apps-ws/">W3C Workshop on The Future of Off-line Web Applications</a> on November 5 in Redwood City. I won&#8217;t be able to attend (I&#8217;ll be heading to <a href="http://velocityconf.com/velocityeu/">Velocity Europe</a>), but I feel like app cache needs improving so I summarized my thoughts and sent it to the workshop organizers. I also pinged some mobile gurus and got their thoughts on app cache.</p>
<h3>My Thoughts</h3>
<div lang="x-western">
<p>SUMMARY: App cache is complicated and frequently produces an unexpected user experience. It&#8217;s also being (ab)used as a workaround for the fact that the browser&#8217;s cache does not cache in an effective way &#8211; this is just an arms race for finite resources.</p>
<p>DETAILS: I&#8217;ve spoken at many mobile-specific conferences and meetups in the last few months. When I explain the way app cache actually works, developers come up afterward and say &#8220;now I finally understand what was happening with my offline app.&#8221; These are the leading mobile developers in the world.</p>
<p>John Allsopp does a <a href="http://www.webdirections.org/blog/get-offline/">great job</a> of outlining the gotchas, and I&#8217;ve added some (<a href="http://stevesouders.com/docs/bdconf-20110912.pptx">slides 50&amp;51</a>):</p>
<ul>
<li>HTML responses with the MANIFEST attribute are stored in app cache by default, even if they&#8217;re not in the CACHE: section of the manifest file.</li>
<li>If a CACHE: resource 404s then none of the resources are cached.</li>
<li>The manifest file must be changed in order for changed CACHE: resources to be updated.</li>
<li>Modified CACHE: resources aren&#8217;t seen by the user until the <em>second time</em> they load the app &#8211; even if they&#8217;re online.</li>
</ul>
<p>It&#8217;s easy to point out problems &#8211; you folks have the more difficult job of finding solutions. But I&#8217;ll make a few suggestions:</p>
<ul>
<li><em>Use updated resources on first load</em> &#8211; The developer needs a way to say &#8220;if the user is online, then fetch (some/all) of the CACHE: resources that have changed before rendering the app&#8221;. I would vote to make this the default behavior, and provide a way to toggle it (in the manifest file or HTML attribute). Perhaps this should also be done at the individual resource level &#8211; &#8220;I want updated scripts to block the initial rendering, but nothing else&#8221;. The manifest file could have an indicator of which resources to check &amp; download before doing the initial rendering.</li>
<li><em>404s</em> &#8211; I haven&#8217;t tested this myself, but it seems like overkill. Every response in the CACHE: section should be cached, independent of the other responses. Perhaps this is browser-specific?</li>
<li><em>updateReady flag</em> &#8211; It&#8217;s great that developers can use the updateReady event to prompt the user to reload the app if any CACHE: resources have changed underneath them, but the bar is too high. In addition, have a flag that indicates that the browser should prompt the user automatically if any CACHE: resources were updated.</li>
</ul>
</div>
<div lang="x-western">
<p>Finally, on the topic of arms race, I know many websites that are using app cache as a way to store images, scripts, and stylesheets. Why? It&#8217;s because the browser&#8217;s disk cache is poorly implemented. App cache provides a dedicated amount of space for a specific website (as opposed to a common shared space). App cache allows for prioritization &#8211; if I have 10M of resources I can put the scripts in the CACHE: section so they don&#8217;t get purged at the expense of less painful images.</p>
<p>Certainly a better solution would be for the browsers to have improved the behavior of disk cache 5 years ago. But given where we are, an increasing number of websites are consuming the user&#8217;s disk space. In most cases the user doesn&#8217;t have a way or doesn&#8217;t know how to clear app cache. Better user control over app cache is needed. I suggest that clearing &#8220;data&#8221; clears both the disk cache as well as app cache. Alternatively, we extend the browser UI to have an obvious &#8220;clear app cache&#8221; entry. Currently in Firefox and Chrome you can only clear app cache on a site-by-site basis, and the UI isn&#8217;t obvious. In Firefox it&#8217;s under Tools | Options | Advanced | Network | Remove. In Chrome it&#8217;s under chrome://appcache-internals/.</p>
<p>The most important near term fix is better patterns and examples.</p>
<ul>
<li>My first offline app had a login form on the index.html &#8211; how should I handle that?</li>
<li>What if the JSON data in app cache requires authentication and the user is offline &#8211; use it or not?</li>
<li>I&#8217;ve never seen an example that uses the FALLBACK: section.</li>
</ul>
<p>Adoption of current app cache would go much more smoothly with patterns and examples that address these gaps, and perhaps a JS helper lib to wrap updateReady and other standard dev tasks.</p>
</div>
<h3 lang="x-western">Mobile Gurus</h3>
<p>A great email thread resulted when I asked a bunch of mobile gurus for their thoughts about app cache. Here&#8217;s a summary of the comments that resulted:</p>
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td style="font-weight: bold; text-align: left; vertical-align: top; padding: 0 1em 1em 0;">Scott Jehl</td>
<td style="padding: 0 1em 1em 0;">Agreed on app cache&#8217;s clumsiness. It&#8217;s so close though! The cache clearing is terrible for both users and developers.</td>
</tr>
<tr>
<td style="font-weight: bold; text-align: left; vertical-align: top; padding: 0 1em 1em 0;">Nicholas Zakas</td>
<td style="padding: 0 1em 1em 0;">+1 for AppCache clumsiness. My big complaint is requiring a special MIME type for the manifest file. This effectively limits its use to people who have access to their server configuration.</td>
</tr>
<tr>
<td style="font-weight: bold; text-align: left; vertical-align: top; padding: 0 1em 1em 0;">Yehuda Katz</td>
<td style="padding: 0 1em 1em 0;">My biggest concern is the lack of a feature that would make it possible to load the main index.html from cache, but only if the user agent is offline.Currently, if the user agent is online, the entire cache manifest, including the main index.html, is used. As a result, developers are required to come up with some non-standard UI to let the application user know that they should refresh the page in order to get more updated information.This is definitely the way to get the most performance, even when the user agent is online, but it creates an extremely clumsy workflow which significantly impedes adoption. I have given a number of talks on the cache manifest, and this caveat is the one that change the audience reaction from nodding heads to &#8220;oh no, another thing I have to spend time working out how to rebuild my application in order to use&#8221;.</p>
<p style="margin-bottom: 0;">Again, I understand the rationale for the design, but I think a way to say &#8220;if the user agent is online, block until the cache manifest is downloaded&#8221; would significantly improve adoption and widen the appropriate use-cases for the technology.</p>
</td>
</tr>
<tr>
<td style="font-weight: bold; text-align: left; vertical-align: top; padding: 0 1em 1em 0;">Scott Jehl</td>
<td style="padding: 0 1em 1em 0;">I agree &#8211; the necessary refresh is the biggest downfall for me, too. It&#8217;s really prohibitive for using appcache in progressive enhancement approaches (where there&#8217;s actually HTML content in the page that may update regularly).It&#8217;d be great if you could set up appcache to kick-in when the user is actually offline, but otherwise stay out of the way and let the browser defer to normal requests and caching.</td>
</tr>
<tr>
<td style="font-weight: bold; text-align: left; vertical-align: top; padding: 0 1em 1em 0;">Yehuda Katz</td>
<td style="padding: 0 1em 1em 0;">I actually think we can get away with a more aggressive approach. When the device is online, first request the application manifest. If the manifest is identical, continue using the app cache. This means a short blocking request for the app manifest, but the (good) atomic cache behavior. If the manifest is not identical, fall back to normal HTTP caching semantics.</p>
<p style="margin-bottom: 0;">It needs to be a single flag in the manifest I think.</p>
</td>
</tr>
<tr>
<td style="font-weight: bold; text-align: left; vertical-align: top; padding: 0 1em 1em 0;">Dion Almaer</td>
<td style="padding: 0 1em 1em 0;">Totally agree. In a recent mobile project we ended up writing our own caching system that had us use HTTP caching&#8230; It was very much a pain to have to do this work.</td>
</tr>
</tbody>
</table>
<p>I like Yehuda&#8217;s suggestion about a blocking manifest check when the user is online controlled by a flag in the manifest file. We need more thinking around how to improve app cache. Please checkout the <a href="http://www.w3.org/2011/web-apps-ws/">W3C Workshop on The Future of Off-line Web Applications</a> website and send them your thoughts.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.stevesouders.com/blog/2011/10/03/improving-app-cache/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
	</channel>
</rss>

