<?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 &#187; Internet Explorer</title>
	<atom:link href="http://www.stevesouders.com/blog/category/internet-explorer/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>Tue, 07 Sep 2010 17:23:33 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Frontend SPOF</title>
		<link>http://www.stevesouders.com/blog/2010/06/01/frontend-spof/</link>
		<comments>http://www.stevesouders.com/blog/2010/06/01/frontend-spof/#comments</comments>
		<pubDate>Wed, 02 Jun 2010 02:49:10 +0000</pubDate>
		<dc:creator>Steve Souders</dc:creator>
				<category><![CDATA[Firefox]]></category>
		<category><![CDATA[IE8]]></category>
		<category><![CDATA[Internet Explorer]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[browsers]]></category>
		<category><![CDATA[custom fonts]]></category>
		<category><![CDATA[font-face]]></category>
		<category><![CDATA[SPOF]]></category>

		<guid isPermaLink="false">http://www.stevesouders.com/blog/?p=1300</guid>
		<description><![CDATA[My evangelism of high performance web sites started off in the context of quality code and development best practices. It&#8217;s easy for a style of coding to permeate throughout a company. Developers switch teams. Code is copied and pasted (especially in the world of web development). If everyone is developing in a high performance way, [...]]]></description>
			<content:encoded><![CDATA[<p>My evangelism of high performance web sites started off in the context of quality code and development best practices. It&#8217;s easy for a style of coding to permeate throughout a company. Developers switch teams. Code is copied and pasted (especially in the world of web development). If everyone is developing in a high performance way, that&#8217;s the style that will characterize how the company codes.</p>
<p>This argument of promoting development best practices gained traction in the engineering quarters of the companies I talked to, but performance improvements continued to get backburnered in favor of new features and content that appealed to the business side of the organization. Improving performance wasn&#8217;t considered as important as other changes. Everyone assumed users wanted new features and that&#8217;s what got the most attention.</p>
<p>It became clear to me that we needed to show a business case for web performance. That&#8217;s why the theme for <a href="http://en.oreilly.com/velocity2009">Velocity 2009</a> was &#8220;the impact of performance on the bottom line&#8221;. Since then there have been <a href="http://blog.mozilla.com/metrics/category/website-optimization/">numerous</a> <a href="http://radar.oreilly.com/2009/07/velocity-making-your-site-fast.html">studies</a> <a href="http://www.stevesouders.com/blog/2009/07/27/wikia-fast-pages-retain-users/">released</a> <a href="http://carsonified.com/blog/business/fred-wilsons-10-golden-principles-of-successful-web-apps/">that</a> <a href="http://www.watchingwebsites.com/archives/proof-that-speeding-up-websites-improves-online-business">have</a> <a href="http://googlewebmastercentral.blogspot.com/2010/04/using-site-speed-in-web-search-ranking.html">shown</a> that improving performance <em>does</em> improve the bottom line. As a result, I&#8217;m seeing the business side of many web companies becoming strong advocates for <a href="http://www.stevesouders.com/blog/2010/05/07/wpo-web-performance-optimization/">Web Performance Optimization</a>.</p>
<p>But there are still occasions when I have a hard time convincing a team that focusing on web performance, specifically frontend performance, is important. Shaving off hundreds (or even thousands) of milliseconds just doesn&#8217;t seem worthwhile to them. That&#8217;s when I pull out the big guns and explain that <em>loading scripts and stylesheets in the typical way creates a frontend single point of failure that can bring down the entire site</em>.</p>
<h2>Examples of Frontend SPOF</h2>
<p>The thought that simply adding a script or stylesheet to your web page could make the entire site unavailable surprises many people. Rather than focusing on CSS mistakes and JavaScript errors, the key is to think about what happens when a resource request times out. With this clue, it&#8217;s easy to create a test case:</p>
<pre style="margin-left: 20px; margin-right: 20px; background: #F0F0F0; padding: 8px; margin-bottom: 0;">&lt;html&gt;
&lt;head&gt;
&lt;script src="http://www.snippet.com/main.js" type="text/javascript"&gt;
  &lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
Here's my page!
&lt;/body&gt;
&lt;/html&gt;</pre>
<p>This HTML page looks pretty normal, but if snippet.com is overloaded the entire page is blank waiting for main.js to return. This is true in all browsers.</p>
<p>Here are some examples of frontend single points of failure and the browsers they impact. You can click on the Frontend SPOF test links to see the actual test page.</p>
<table style="margin-left: 20px;" border="1" cellspacing="0" cellpadding="4">
<tbody>
<tr>
<th>Frontend SPOF test</th>
<th>Chrome</th>
<th>Firefox</th>
<th>IE</th>
<th>Opera</th>
<th>Safari</th>
</tr>
<tr>
<td><a href="http://stevesouders.com/tests/spof/slow-script.php">External Script</a></td>
<td style="text-align: center; background: #F7D6D6;">blank below</td>
<td style="text-align: center; background: #F7D6D6;">blank below</td>
<td style="text-align: center; background: #F7D6D6;">blank below</td>
<td style="text-align: center; background: #F7D6D6;">blank below</td>
<td style="text-align: center; background: #F7D6D6;">blank below</td>
</tr>
<tr>
<td><a href="http://stevesouders.com/tests/spof/slow-stylesheet.php">Stylesheet</a></td>
<td style="text-align: center; background: #F7D6D6;">blank below</td>
<td style="text-align: center; background: #DFFCD8;">flash</td>
<td style="text-align: center; background: #F7D6D6;">blank below</td>
<td style="text-align: center; background: #DFFCD8;">flash</td>
<td style="text-align: center; background: #F7D6D6;">blank below</td>
</tr>
<tr>
<td><a href="http://stevesouders.com/tests/spof/slow-font.php">inlined @font-face</a></td>
<td style="text-align: center; background: #FFFFD6;">delayed</td>
<td style="text-align: center; background: #DFFCD8;">flash</td>
<td style="text-align: center; background: #DFFCD8;">flash</td>
<td style="text-align: center; background: #DFFCD8;">flash</td>
<td style="text-align: center; background: #FFFFD6;">delayed</td>
</tr>
<tr>
<td><a href="http://stevesouders.com/tests/spof/slow-font-stylesheet.php">Stylesheet with @font-face</a></td>
<td style="text-align: center; background: #FFFFD6;">delayed</td>
<td style="text-align: center; background: #DFFCD8;">flash</td>
<td style="text-align: center; background: #F7D6D6;">totally blank</td>
<td style="text-align: center; background: #DFFCD8;">flash</td>
<td style="text-align: center; background: #FFFFD6;">delayed</td>
</tr>
<tr>
<td><a href="http://stevesouders.com/tests/spof/slow-font-script.php">Script then @font-face</a></td>
<td style="text-align: center; background: #FFFFD6;">delayed</td>
<td style="text-align: center; background: #DFFCD8;">flash</td>
<td style="text-align: center; background: #F7D6D6;">totally blank</td>
<td style="text-align: center; background: #DFFCD8;">flash</td>
<td style="text-align: center; background: #FFFFD6;">delayed</td>
</tr>
</tbody>
</table>
<p>The failure cases are highlighted in red. Here are the four possible outcomes sorted from worst to best:</p>
<ul>
<li><em>totally blank</em> &#8211; Nothing in the page is rendered &#8211; the entire page is blank.</li>
<li><em>blank below</em> &#8211; All the DOM elements below the resource in question are not rendered.</li>
<li><em>delayed</em> &#8211; Text that uses the @font-face style is invisible until the font file arrives.</li>
<li><em>flash</em> &#8211; DOM elements are rendered immediately, and then redrawn if necessary after the stylesheet or font has finished downloading.</li>
</ul>
<h2>Web Performance avoids SPOF</h2>
<p>It turns out that there are web performance best practices that, in addition to making your pages faster, also avoid most of these frontend single points of failure. Let&#8217;s look at the tests one by one.</p>
<dl>
<dt><strong><a href="http://stevesouders.com/tests/spof/slow-script.php">External Script</a></strong></p>
</dt>
<dd style="margin-bottom: 10px;">All browsers block rendering of elements below an external script until the script arrives and is parsed and executed. Since many sites put scripts in the HEAD, this means the entire page is typically blank. That&#8217;s why I believe the most important web performance coding pattern for today&#8217;s web sites is to <a href="http://www.stevesouders.com/blog/2009/04/27/loading-scripts-without-blocking/">load JavaScript asynchronously</a>. Not only does this improve performance, but it avoids making external scripts a possible SPOF.</p>
</dd>
<dt><strong><a href="http://stevesouders.com/tests/spof/slow-stylesheet.php">Stylesheet</a></strong></p>
</dt>
<dd style="margin-bottom: 10px;">Browsers are split on how they handle stylesheets. Firefox and Opera charge ahead and render the page, and then flash the user if elements have to be redrawn because their styling changed. Chrome, Internet Explorer, and Safari delay rendering the page until the stylesheets have arrived. (Generally they only delay rendering elements below the stylesheet, but in <a href="http://stevesouders.com/hpws/css-bottom.php">some cases</a> IE will delay rendering everything in the page.) If rendering is blocked and the stylesheet takes a long time to download, or times out, the user is left staring at a blank page. There&#8217;s not a lot of advice on loading stylesheets without blocking page rendering, primarily because it would introduce the <a href="http://www.bluerobot.com/web/css/fouc.asp/">flash of unstyled content</a>. </dd>
<dt><strong><a href="http://stevesouders.com/tests/spof/slow-font.php">inlined @font-face</a></strong></p>
</dt>
<dd style="margin-bottom: 10px;">I&#8217;ve blogged before about the <a href="http://www.stevesouders.com/blog/2009/10/13/font-face-and-performance/">performance implications of using @font-face</a>. When the @font-face style is declared in a STYLE block in the HTML document, the SPOF issues are dramatically reduced. Firefox, Internet Explorer, and Opera avoid making these custom font files a SPOF by rendering the affected text and then redrawing it after the font file arrives. Chrome and Safari don&#8217;t render the customized text at all until the font file arrives. I&#8217;ve drawn these cells in yellow since it could cause the page to be unusable for users using these browsers, but most sites only use custom fonts on a subset of the page. </dd>
<dt><strong><a href="http://stevesouders.com/tests/spof/slow-font-stylesheet.php">Stylesheet with @font-face</a></strong></p>
</dt>
<dd style="margin-bottom: 10px;">Inlining your @font-face style is the key to avoiding having font files be a single point of failure. If you inline your @font-face styles and the font file takes forever to return or times out, the worst case is the affected text is invisible in Chrome and Safari. But at least the rest of the page is visible, and everything is visible in Firefox, IE, and Opera. Moving the @font-face style to a stylesheet not only slows down your site (by requiring two sequential downloads to render text), but it also creates a special case in Internet Explorer 7 &amp; 8 where the entire page is blocked from rendering. IE 6 is only slightly better &#8211; the elements below the stylesheet are blocked from rendering (but if your stylesheet is in the HEAD this is the same outcome). </dd>
<dt><strong><a href="http://stevesouders.com/tests/spof/slow-font-script.php">Script then @font-face</a></strong></p>
</dt>
<dd>Inlining your @font-face style isn&#8217;t enough to avoid the entire page SPOF that occurs in IE. You also have to make sure the inline STYLE block isn&#8217;t preceded by a SCRIPT tag. Otherwise, your entire page is blank in IE waiting for the font file to arrive. If that file is slow to return, your users are left staring at a blank page. </dd>
</dl>
<h2>SPOF is bad</h2>
<p>Five years ago most of the attention on web performance was focused on the backend. Since then we&#8217;ve learned that 80% of the time users wait for a web page to load is the responsibility of the frontend. I feel this same bias when it comes to identifying and guarding against single points of failure that can bring down a web site &#8211; the focus is on the backend and there&#8217;s not enough focus on the frontend. For larger web sites, the days of a single server, single router, single data center, and other backend SPOFs are way behind us. And yet, most major web sites include scripts and stylesheets in the typical way that creates a frontend SPOF. Even more worrisome &#8211; many of these scripts are from third parties for social widgets, web analytics, and ads.</p>
<p>Look at the scripts, stylesheets, and font files in your web page from a worst case scenario perspective. Ask yourself:</p>
<ul>
<li>Is your web site&#8217;s availability dependent on these resources?</li>
<li>Is it possible that if one of these resources timed out, users would be blocked from seeing your site?</li>
<li>Are any of these single point of failure resources from a third party?</li>
<li>Would you rather embed resources in a way that avoids making them a frontend SPOF?</li>
</ul>
<p>Make sure you&#8217;re aware of your frontend SPOFs, track their availability and latency closely, and embed them in your page in a non-blocking way whenever possible.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.stevesouders.com/blog/2010/06/01/frontend-spof/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Call to improve browser caching</title>
		<link>http://www.stevesouders.com/blog/2010/04/26/call-to-improve-browser-caching/</link>
		<comments>http://www.stevesouders.com/blog/2010/04/26/call-to-improve-browser-caching/#comments</comments>
		<pubDate>Tue, 27 Apr 2010 08:14:09 +0000</pubDate>
		<dc:creator>Steve Souders</dc:creator>
				<category><![CDATA[Chrome]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[Internet Explorer]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[browsers]]></category>
		<category><![CDATA[caching]]></category>
		<category><![CDATA[lru]]></category>

		<guid isPermaLink="false">http://www.stevesouders.com/blog/?p=1185</guid>
		<description><![CDATA[Over Christmas break I wrote Santa my browser wishlist. There was one item I neglected to ask for: improvements to the browser disk cache.
In 2007 Tenni Theurer and I ran an experiment to measure browser cache stats from the server side. Tenni&#8217;s write up, Browser Cache Usage &#8211; Exposed, is the stuff of legend. There [...]]]></description>
			<content:encoded><![CDATA[<p>Over Christmas break I wrote Santa my <a href="http://www.stevesouders.com/blog/2010/02/15/browser-performance-wishlist/">browser wishlist</a>. There was one item I neglected to ask for: improvements to the browser disk cache.</p>
<p>In 2007 Tenni Theurer and I ran an experiment to measure browser cache stats from the server side. Tenni&#8217;s write up, <a href="http://www.yuiblog.com/blog/2007/01/04/performance-research-part-2/">Browser Cache Usage &#8211; Exposed</a>, is the stuff of legend. There she reveals that while 80% of page views were done with a <em>primed cache</em>, 40-60% of unique users hit the site with an <em>empty cache </em>at least once per day. 40-60% seems high, but I&#8217;ve heard similar numbers from respected web devs at other major sites.</p>
<p><em>Why do so many users have an empty cache at least once per day?</em></p>
<p>I&#8217;ve been racking my brain for years trying to answer this question. Here are some answers I&#8217;ve come up with:</p>
<ul>
<li> <strong>first time users</strong> &#8211; Yea, but not 40-60%.</li>
<li> <strong>cleared cache</strong> &#8211; It&#8217;s true: more and more people are likely using anti-virus software that clears the cache between browser sessions. And since we ran that experiment back in 2007 many browsers have added options for clearing the cache frequently (for example, Firefox&#8217;s privacy.clearOnShutdown.cache option). But again, this doesn&#8217;t account for the 40-60% number.</li>
<li> <strong>flawed experiment</strong> &#8211; It turns out there was a flaw in the experiment (browsers ignore caching headers when an image is in memory), but this would only affect the 80% number, not the 40-60% number. And I expect the impact on the 80% number is small, given the fact that other folks have gotten similar numbers. (In a future blog post I&#8217;ll share a new experiment design I&#8217;ve been working on.)</li>
<li> <strong>resources got evicted</strong> &#8211; hmmmmm</li>
</ul>
<p>OK, let&#8217;s talk about eviction for a minute. The two biggest influencers for a resource getting evicted are the size of the cache and the eviction algorithm. It turns out, the amount of disk space used for caching hasn&#8217;t kept pace with the size of people&#8217;s drives and their use of the Web. Here are the default disk cache sizes for the major browsers:</p>
<ul>
<li> Internet Explorer: 8-50 MB</li>
<li> Firefox: 50 MB</li>
<li> Safari: everything I found said there isn&#8217;t a max size setting (???)</li>
<li> Chrome: &lt; 80 MB (varies depending on available disk space)</li>
<li> Opera: 20 MB</li>
</ul>
<p>Those defaults are too small. My disk drive is 150 GB of which 120 GB is free. I&#8217;d gladly give up 5 GB or more to raise the odds of web pages loading faster.</p>
<p>Even with more disk space, the cache is eventually going to fill up. When that happens, cached resources need to be evicted to make room for the new ones. Here&#8217;s where eviction algorithms come into play. Most eviction algorithms are LRU-based &#8211; the resource that was least recently used is evicted. However, our knowledge of performance pain points has grown dramatically in the last few years. Translating this knowledge into eviction algorithm improvements makes sense. For example, we&#8217;re all aware how much costlier it is to download a script than an image. (Scripts block other downloads and rendering.) Scripts, therefore, should be given a higher priority when it comes to caching.</p>
<p>It&#8217;s hard to get access to gather browser disk cache stats, so I&#8217;m asking people to discover their own settings and share them via the <a href="http://spreadsheets.google.com/viewform?formkey=dGlFb2FUb0NfeUFfRklLeTZmanZCb1E6MQ">Browser Disk Cache Survey form</a>. I included this in my talks at <a href="http://jsconf.us/2010/">JSConf</a> and <a href="http://events.jquery.org/2010/sf-bay-area/">jQueryConf</a>. ~150 folks at those conferences filled out the form. The data shows that <em><strong>55% of people surveyed have a cache that&#8217;s over 90% full</strong></em>. (Caveats: this is a small sample size and the data is self-reported.) It would be great if you would take time to fill out <a href="http://spreadsheets.google.com/viewform?formkey=dGlFb2FUb0NfeUFfRklLeTZmanZCb1E6MQ">the form</a>. I&#8217;ve also started writing <a href="http://stevesouders.com/cache.php">instructions for finding your cache settings</a>.</p>
<p>I&#8217;m optimistic about the potential speedup that could result from improving browser caching, and fortunately browser vendors seem receptive (for example, the recent <a href="http://ajaxian.com/archives/mozilla-web-caching-summit">Mozilla Caching Summit</a>). I expect we&#8217;ll see better default cache sizes and eviction logic in the next major release of each browser. Until then, jack up your defaults as described in the <a href="http://stevesouders.com/cache.php">instructions</a>. And please add comments for any browsers I left out or got wrong. Thanks.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.stevesouders.com/blog/2010/04/26/call-to-improve-browser-caching/feed/</wfw:commentRss>
		<slash:comments>33</slash:comments>
		</item>
		<item>
		<title>Browser Performance Wishlist</title>
		<link>http://www.stevesouders.com/blog/2010/02/15/browser-performance-wishlist/</link>
		<comments>http://www.stevesouders.com/blog/2010/02/15/browser-performance-wishlist/#comments</comments>
		<pubDate>Tue, 16 Feb 2010 00:25:17 +0000</pubDate>
		<dc:creator>Steve Souders</dc:creator>
				<category><![CDATA[Chrome]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[IE8]]></category>
		<category><![CDATA[Internet Explorer]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[browsers]]></category>
		<category><![CDATA[frag tag]]></category>
		<category><![CDATA[Opera]]></category>
		<category><![CDATA[Safari]]></category>
		<category><![CDATA[SPDY]]></category>

		<guid isPermaLink="false">http://www.stevesouders.com/blog/?p=927</guid>
		<description><![CDATA[What are the most important changes browsers could make to improve  performance?
This document is my answer to that question. This is mainly for browser developers, although web developers will want to track the adoption of these improvements.

 download  scripts without blocking
 SCRIPT  attributes
 resource  packages
 border-radius
 cache  redirects
 link  [...]]]></description>
			<content:encoded><![CDATA[<p><em>What are the most important changes browsers could make to improve  performance?</em></p>
<p>This document is my answer to that question. This is mainly for browser developers, although web developers will want to track the adoption of these improvements.</p>
<ul>
<li> <a href="#download_scripts">download  scripts without blocking</a></li>
<li> <a href="#script_attributes">SCRIPT  attributes</a></li>
<li> <a href="#resource_packages">resource  packages</a></li>
<li> <a href="#border_radios">border-radius</a></li>
<li> <a href="#cache_redirects">cache  redirects</a></li>
<li> <a href="#link_prefetch">link  prefetch</a></li>
<li> <a href="#web_timing">Web  Timing spec</a></li>
<li> <a href="#remote_js">remote  JS debugging</a></li>
<li> <a href="#web_sockets">Web  Sockets</a></li>
<li> <a href="#history">History</a></li>
<li> <a href="#anchor_ping">anchor  ping</a></li>
<li> <a href="#progressive_xhr">progressive  XHR</a></li>
<li> <a href="#stylesheet_js">stylesheet  &amp; inline JS</a></li>
<li> <a href="#script_defer">SCRIPT  DEFER for inline scripts</a></li>
<li> <a href="#import_improvements">@import  improvements</a></li>
<li> <a href="#font_face">@font-face  improvements</a></li>
<li> <a href="#stylesheets_iframes">stylesheets  &amp; iframes</a></li>
<li> <a href="#paint_events">paint  events</a></li>
<li> <a href="#missing_schema">missing  schema, double downloads</a></li>
</ul>
<p>Before digging into the list I wanted to mention two items that would  actually be at the top of the list if it wasn&#8217;t for how new they are: <em>SPDY</em> and <em>FRAG tag</em>. Both of these require industry adoption and possible changes to  specifications, so it&#8217;s too soon to put them on an implementation  wishlist. I hope these ideas gain consensus soon and to facilitate that I describe  them here.</p>
<dl>
<dt style="font-weight: bold; margin-bottom: 4px; font-size: 1.1em;"> SPDY  <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/ie-icon.png" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/firefox-32-noshadow.png" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/safari-icon.gif" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/chrome32.gif" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/opera.png" alt="" /> </dt>
<dd style="margin-bottom: 14px;"> SPDY is a <a href="http://blog.chromium.org/2009/11/2x-faster-web.html">proposal from  Google</a> for making three major improvements to HTTP: compressed  headers, multiplexed requests, and prioritized responses. Initial studies showed 25 top sites were loaded 55% faster. Server and client implementations are available, and some other  organizations and individuals have completed server and client  implementations. The <a href="http://dev.chromium.org/spdy/spdy-protocol">protocol</a> draft has been published for review. </dd>
<dt style="font-weight: bold; margin-bottom: 4px; font-size: 1.1em;"> FRAG tag  <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/ie-icon.png" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/firefox-32-noshadow.png" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/safari-icon.gif" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/chrome32.gif" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/opera.png" alt="" /> </dt>
<dd style="margin-bottom: 14px;">The idea behind this &#8220;document fragment&#8221; tag is that it be used to wrap 3rd party content &#8211; ads,  widgets, and analytics. 3rd party content can have a severe impact on the containing page&#8217;s  performance due to additional HTTP requests, scripts that block  rendering and downloads, and added DOM nodes. Many of these factors can be mitigated by putting the 3rd party content  inside an iframe embedded in the top level HTML document. But iframes have constraints and drawbacks &#8211; they typically introduce  another HTTP request for the iframe&#8217;s HTML document, not all 3rd party  code snippets will work inside an iframe without changes (e.g.,  references to &#8220;document&#8221; in JavaScript might need to reference the  parent document), and some snippets (expando ads, suggest) can&#8217;t float  over the main page&#8217;s elements. Another path to mitigate these issues is to load the JavaScript  asynchronously, but many of these widgets use document.write and so must  be evaluated synchronously.</p>
<p>A compromise is to place 3rd party content in the top level HTML  document wrapped in a FRAG block. This approach degrades nicely &#8211; older browsers would ignore the FRAG tag  and handle these snippets the same way they do today. Newer browsers would parse the HTML in a separate document fragment. The FRAG content would not block the rendering of the top level  document. Snippets containing document.write would work without blocking the top  level document. This idea just started getting discussed in January 2010. Much more use case analysis and discussion is needed, culminating in a  proposed specification. (Credit to Alex Russell for the idea and name.)</p>
</dd>
</dl>
<h1>The List</h1>
<p>The performance wishlist items are sorted highest priority first. The browser icons indicate which browsers need to implement that  particular improvement.</p>
<dl><a name="download_scripts"></a></p>
<dt style="font-weight: bold; margin-bottom: 4px; font-size: 1.1em;"> download scripts without blocking  <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/ie-icon.png" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/firefox-32-noshadow.png" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/safari-icon.gif" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/chrome32.gif" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/opera.png" alt="" /> </dt>
<dd style="margin-bottom: 14px;"> In older  browsers, once a script started downloading all subsequent downloads  were blocked until the script returned. It&#8217;s critical that scripts be evaluated in the order specified, but they  can be downloaded in parallel. This has a significant improvement on page load times, especially for  pages with multiple scripts. Newer browsers (IE8, Firefox 3.5+, Safari 4, Chrome 2+) incorporated  this parallel script loading feature, but it doesn&#8217;t work as proactively  as it could. Specifically:</p>
<ul>
<li> IE8 &#8211; downloading scripts blocks image and iframe downloads</li>
<li> Firefox 3.6 &#8211; downloading scripts blocks iframe downloads</li>
<li> Safari 4 &#8211; downloading scripts blocks iframe downloads</li>
<li> Chrome 4 &#8211; downloading scripts blocks iframe downloads</li>
<li> Opera 10.10 &#8211; downloading scripts blocks all downloads</li>
</ul>
<p>(<a href="http://www.browserscope.org/?category=network&amp;v=top">test  case</a>, see the four &#8220;|| Script [Script|Stylesheet|Image|Iframe]&#8221;  tests)     <a name="script_attributes"></a></p>
</dd>
<dt style="font-weight: bold; margin-bottom: 4px; font-size: 1.1em;"> SCRIPT attributes  <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/ie-icon.png" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/firefox-32-noshadow.png" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/safari-icon.gif" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/chrome32.gif" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/opera.png" alt="" /> </dt>
<dd style="margin-bottom: 14px;"> The HTML5  specification describes the <a href="http://www.w3.org/TR/2008/WD-html5-20080610/tabular.html#defer">ASYNC  and DEFER attributes</a> for the SCRIPT tag, but the implementation  behavior is not specified. Here&#8217;s how the SCRIPT attributes should work.</p>
<ul>
<li> DEFER &#8211; The HTTP request for a SCRIPT with the DEFER attribute is  not made until all other resources in the page on the same domain have  already been sent. This is so that it doesn&#8217;t occupy one of the limited number of  connections that are opened for a single server. Deferred scripts are downloaded in parallel, but are executed in the  order they occur in the HTML document, regardless of what order the  responses arrive in. The window&#8217;s onload event fires after all deferred scripts are  downloaded and executed.</li>
<li> ASYNC &#8211; The HTTP request for a SCRIPT with the ASYNC attribute is made immediately. Async scripts are executed as soon as the response is received,  regardless of the order they occur in the HTML document. The window&#8217;s onload event fires after all async scripts are downloaded  and executed.</li>
<li> POSTONLOAD &#8211; This is a new attribute I&#8217;m proposing. Postonload scripts don&#8217;t start downloading until after the window&#8217;s  onload event has fired. By default, postonload scripts are evaluated in the order they occur in  the HTML document. POSTONLOAD and ASYNC can be used in combination to cause postonload  scripts to be evaluated as soon as the response is received, regardless  of the order they occur in the HTML document.</li>
</ul>
<p><a name="resource_packages"></a></p>
</dd>
<dt style="font-weight: bold; margin-bottom: 4px; font-size: 1.1em;"> resource packages  <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/ie-icon.png" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/firefox-32-noshadow.png" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/safari-icon.gif" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/chrome32.gif" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/opera.png" alt="" /> </dt>
<dd style="margin-bottom: 14px;"> Each HTTP  request has some overhead cost. Workarounds include concatenating scripts, concatenating stylesheets,  and creating image sprites. But this still results in multiple HTTP requests. And sprites are especially difficult to create and maintain. Alexander Limi (Mozilla) has <a href="http://limi.net/articles/resource-packages/">proposed</a> using  zip files to create resource packages. It&#8217;s a good idea because of its simplicity and graceful degradation.      <a name="border_radius"></a> </dd>
<dt style="font-weight: bold; margin-bottom: 4px; font-size: 1.1em;"> border-radius  <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/ie-icon.png" alt="" /> </dt>
<dd style="margin-bottom: 14px;"> Creating  rounded corners leads to code bloat and excessive HTTP requests. Border-radius reduces this to a simple CSS style. The only major browser that doesn&#8217;t support border-radius is IE. It has already been announced that <a href="http://blogs.msdn.com/ie/archive/2009/11/18/an-early-look-at-ie9-for-developers.aspx">IE9  will support border-radius</a>, but I wanted to include it  nevertheless.     <a name="cache_redirects"></a> </dd>
<dt style="font-weight: bold; margin-bottom: 4px; font-size: 1.1em;"> cache redirects  <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/ie-icon.png" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/safari-icon.gif" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/opera.png" alt="" /> </dt>
<dd style="margin-bottom: 14px;"> Redirects are  costly from a performance perspective, especially for users with high  latency. Although the <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3">HTTP  spec</a> says 301 and 302 responses (with the proper HTTP headers) are  cacheable,  most browsers don&#8217;t support this.</p>
<ul>
<li> IE8 &#8211; doesn&#8217;t cache redirects for the main page and for resources</li>
<li> Safari 4 &#8211; doesn&#8217;t cache redirects for the main page</li>
<li> Opera 10.10 &#8211; doesn&#8217;t cache redirects for the main page</li>
</ul>
<p>(<a href="http://www.browserscope.org/?category=network&amp;v=top">test  case</a>)     <a name="link_prefetch"></a></p>
</dd>
<dt style="font-weight: bold; margin-bottom: 4px; font-size: 1.1em;"> link prefetch  <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/ie-icon.png" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/safari-icon.gif" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/chrome32.gif" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/opera.png" alt="" /> </dt>
<dd style="margin-bottom: 14px;"> To improve  page load times, developers prefetch resources that are likely or  certain to be used later in the user&#8217;s session. This typically involves writing JavaScript code that executes after the  onload event. When prefetching scripts and stylesheets, an iframe must be used to  avoid conflict with the JavaScript and CSS in the main page. Using an iframe makes this prefetching code more complex. A final burden is the processing required to parse prefetched scripts  and stylesheets.  The browser UI can freeze while prefetched scripts and stylesheets are  parsed, even though this is unnecessary as they&#8217;re not going to be used  in the current page. A simple alternative solution is to use <a href="http://www.w3.org/TR/2009/WD-html5-20090423/history.html#link-type-prefetch">LINK  PREFETCH</a>. Firefox is the only major browser that supports this feature (since  1.0). Wider support of LINK PREFETCH would give developers an easy way to  accelerate their web pages. (<a href="http://www.browserscope.org/?category=network&amp;v=top">test  case</a>)     <a name="web_timing"></a> </dd>
<dt style="font-weight: bold; margin-bottom: 4px; font-size: 1.1em;"> Web Timing spec  <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/ie-icon.png" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/firefox-32-noshadow.png" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/safari-icon.gif" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/chrome32.gif" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/opera.png" alt="" /> </dt>
<dd style="margin-bottom: 14px;"> In order for  web developers to improve the performance of their web sites, they need  to be able to measure their performance &#8211; specifically their page load  times. There&#8217;s debate on the endpoint for measuring page load times (window  onload event, first paint event, onDomReady), but most people agree that  the starting point is when the web page is requested by the user. And yet, there is no reliable way for the owner of the web page to  measure from this starting point. Google has submitted the <a href="http://dev.w3.org/2006/webapi/WebTiming/">Web Timing proposal  draft</a> for browser builtin support for measuring page load times to  address these issues.     <a name="remote_js"></a> </dd>
<dt style="font-weight: bold; margin-bottom: 4px; font-size: 1.1em;"> remote JS debugging  <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/ie-icon.png" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/firefox-32-noshadow.png" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/safari-icon.gif" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/chrome32.gif" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/opera.png" alt="" /> </dt>
<dd style="margin-bottom: 14px;"> Developers  strive to make their web apps fast across all major browsers, but this  requires installing and learning a different toolset for each browser. In order to get cross-browser web development tools, browsers need to  support remote JavaScript debugging. There&#8217;s been progress in building protocols to support remote debugging:  <a href="http://groups.google.com/group/webdebugprotocol?hl=en">WebDebugProtocol</a> and  <a href="http://getfirebug.com/wiki/index.php/Crossfire">Crossfire</a> in Firefox, <a href="http://dragonfly.opera.com/app/scope-interface/">Scope</a> in Opera, and  <a href="http://code.google.com/p/chromedevtools/">ChromeDevTools</a> in  Chrome. Agreement on the preferred protocol and support in the major browsers  would go a long way to getting faster web apps for all users,  and reducing the work for developers to maintain cross-browser web app  performance.     <a name="web_sockets"></a> </dd>
<dt style="font-weight: bold; margin-bottom: 4px; font-size: 1.1em;"> Web Sockets  <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/ie-icon.png" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/firefox-32-noshadow.png" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/safari-icon.gif" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/opera.png" alt="" /> </dt>
<dd style="margin-bottom: 14px;"> <a href="http://dev.w3.org/html5/websockets/">HTML5 Web Sockets</a> provide  built-in support for two-way communications between the client and  server. The communication channel is accessible via JavaScript. Web Sockets are superior to comet and Ajax, especially in their  compatibility with proxies and firewalls, and provide a path for building web apps with a high degree of  communication between the browser and server.     <a name="history"></a> </dd>
<dt style="font-weight: bold; margin-bottom: 4px; font-size: 1.1em;"> History  <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/ie-icon.png" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/firefox-32-noshadow.png" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/safari-icon.gif" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/chrome32.gif" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/opera.png" alt="" /> </dt>
<dd style="margin-bottom: 14px;"> HTML5  specifies implementation for <a href="http://dev.w3.org/html5/spec-author-view/history.html">History.pushState  and History.replaceState</a>.  With these, web developers can dynamically change the URL to reflect the  web application state without having to perform a page transition. This is important for Web 2.0 applications that modify the state of the  web page using Ajax. Being able to avoid fetching a new HTML document to reflect these  application changes results in a faster user experience.     <a name="anchor_ping"></a> </dd>
<dt style="font-weight: bold; margin-bottom: 4px; font-size: 1.1em;"> anchor ping  <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/ie-icon.png" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/firefox-32-noshadow.png" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/safari-icon.gif" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/chrome32.gif" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/opera.png" alt="" /> </dt>
<dd style="margin-bottom: 14px;"> The <a href="http://www.w3.org/TR/html5/history.html#ping">ping attribute</a> for anchors provides a more performant way to track links. This is a controversial feature because of the association with  &#8220;tracking&#8221; users. However, links are tracked today, it&#8217;s just done in a way that hurts the  user experience. For example, redirects, synchronous XHR, and tight loops in unload  handlers are some of the techniques used to ensure clicks are properly recorded. All of these create a slower user experience.     <a name="progressive_xhr"></a> </dd>
<dt style="font-weight: bold; margin-bottom: 4px; font-size: 1.1em;"> progressive XHR  <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/ie-icon.png" alt="" /> </dt>
<dd style="margin-bottom: 14px;"> The draft  spec for XMLHttpRequest details how XHRs are to support <a href="http://www.w3.org/TR/XMLHttpRequest/#the-responsetext-attribute">progressive  response handling</a>. This is important for web apps that use data with varied response times  as well as comet-style applications. (<a href="http://www.kylescholz.com/blog/2010/01/progressive_xmlhttprequest_1.html">more  information</a>)     <a name="stylesheet_js"></a> </dd>
<dt style="font-weight: bold; margin-bottom: 4px; font-size: 1.1em;"> stylesheet &amp; inline JS  <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/ie-icon.png" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/firefox-32-noshadow.png" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/safari-icon.gif" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/chrome32.gif" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/opera.png" alt="" /> </dt>
<dd style="margin-bottom: 14px;"> When a  stylesheet is followed by an inline script, resources that follow are  blocked until the stylesheet is downloaded and the inline script is  evaluated. Browsers should instead lookahead in their parsing and start downloading  subsequent resources in parallel with the stylesheet. These resources of course would not be rendered, parsed, or evaluated  until after the stylesheet was parsed and the inline script was  evaluated. (<a href="http://www.browserscope.org/?category=network&amp;v=top">test  case</a> see &#8220;|| CSS + Inline Script&#8221;; looks like this just landed in Firefox 3.6!)     <a name="script_defer"></a> </dd>
<dt style="font-weight: bold; margin-bottom: 4px; font-size: 1.1em;"> SCRIPT DEFER for inline scripts  <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/firefox-32-noshadow.png" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/safari-icon.gif" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/chrome32.gif" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/opera.png" alt="" /> </dt>
<dd style="margin-bottom: 14px;"> The benefit  of the SCRIPT DEFER attribute for external scripts is discussed <a href="#script_attributes">above</a>.   But DEFER is also useful for inline scripts that can be executed after  the page has been parsed. Currently, IE8 supports this behavior. (<a href="http://stevesouders.com/cuzillion/?c0=hb0hfft0_2_f&amp;c1=hb0hfff0_0_f&amp;c2=hj1hfff2_0_f">test  case</a>)     <a name="import_improvements"></a> </dd>
<dt style="font-weight: bold; margin-bottom: 4px; font-size: 1.1em;"> @import improvements  <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/ie-icon.png" alt="" /> </dt>
<dd style="margin-bottom: 14px;"> @import is a  popular alternative to the LINK tag for loading stylesheets, but it has  several performance problems in IE:</p>
<ul>
<li> LINK @import &#8211; If the first stylesheet is loaded using LINK and  the second one uses @import, they are loaded sequentially instead of in  parallel. (<a href="http://stevesouders.com/tests/atimport/link-import.php">test  case</a>)</li>
<li> LINK blocks @import &#8211; If the first stylesheet is loaded  using LINK, and the second stylesheet is loaded using LINK that contains  @import,  that @import stylesheet is blocked from downloading until the first  stylesheet response is received. It would be better to start downloading the @import stylesheet  immediately. (<a href="http://stevesouders.com/tests/atimport/link-blocks-import.php">test  case</a>)</li>
<li> many @imports &#8211; Using @import can change the download  sequence of resources. In this <a href="http://stevesouders.com/tests/atimport/many-imports.php">test case</a>,  multiple stylesheets loaded with @import are followed by a script. Even though the script is listed last in the HTML document, it gets  downloaded first.  If the script takes a long time to download, it can causes the  stylesheet downloads to be delayed, which can cause rendering to be  delayed. It would be better to follow the order specified in the HTML document. (<a href="http://stevesouders.com/tests/atimport/many-imports.php">test  case</a>)</li>
</ul>
<p>(<a href="../2009/04/09/dont-use-import/">more  information</a>)     <a name="font_face"></a></p>
</dd>
<dt style="font-weight: bold; margin-bottom: 4px; font-size: 1.1em;"> @font-face improvements  <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/ie-icon.png" alt="" /> </dt>
<dd style="margin-bottom: 14px;"> In IE8, if a  script occurs before a style that uses @font-face, the page is blocked  from rendering until the font file is done downloading. It would be better to render the rest of the page without waiting for  the font file. (<a href="../../tests/font-face/fout.php">test  case</a>, <a href="../2009/10/13/font-face-and-performance/">blog  post</a>)     <a name="stylesheets_iframes"></a> </dd>
<dt style="font-weight: bold; margin-bottom: 4px; font-size: 1.1em;"> stylesheets &amp; iframes  <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/ie-icon.png" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/firefox-32-noshadow.png" alt="" /> </dt>
<dd style="margin-bottom: 14px;"> When an iframe is preceded by an external stylesheet, it blocks iframe  downloads. In IE, the iframe is blocked from downloading until the stylesheet  response is received. In Firefox, the iframe&#8217;s resources are blocked from downloading until  the stylesheet response is received. There&#8217;s no dependency between the parent&#8217;s stylesheet and the iframe&#8217;s  HTML document, so this blocking behavior should be removed. (<a href="http://stevesouders.com/efws/stylesheet-before-iframe.php">test  case</a>)     <a name="paint_events"></a> </dd>
<dt style="font-weight: bold; margin-bottom: 4px; font-size: 1.1em;"> paint events  <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/ie-icon.png" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/safari-icon.gif" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/chrome32.gif" alt="" /> <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/opera.png" alt="" /> </dt>
<dd style="margin-bottom: 14px;"> As the amount  of DOM elements and CSS grows, it&#8217;s becoming more important to be able  to measure the performance of painting the page. Firefox 3.5 added the <a href="https://developer.mozilla.org/en/Gecko-Specific_DOM_Events">MozAfterPaint  event</a> which opened the door for add-ons like <a href="https://addons.mozilla.org/en-US/firefox/addon/9620">Firebug Paint  Events</a> (although early Firefox documentation noted that the &#8220;<a href="https://developer.mozilla.org/web-tech/2008/10/13/mozafterpaint/">event  might fire before the actual repainting happens</a>&#8220;).  Support for accurate paint events will allow developers to capture these  metrics.     <a name="missing_schema"></a> </dd>
<dt style="font-weight: bold; margin-bottom: 4px; font-size: 1.1em;"> missing schema, double downloads  <img style="height: 20px; vertical-align: top;" src="http://stevesouders.com/images/ie-icon.png" alt="" /> </dt>
<dd style="margin-bottom: 14px;"> In  IE7&amp;8, if the &#8220;http:&#8221; schema is missing from a stylesheet&#8217;s URL, the  stylesheet is downloaded twice. This makes the page render more slowly. Not including &#8220;http://&#8221; in URLs is not pervasive, but it&#8217;s getting more  widely adopted because it reduces download size and resolves to &#8220;http://&#8221; or &#8220;https://&#8221; as appropriate. (<a href="http://stevesouders.com/tests/missing-schema.php">test case</a>) </dd>
</dl>
]]></content:encoded>
			<wfw:commentRss>http://www.stevesouders.com/blog/2010/02/15/browser-performance-wishlist/feed/</wfw:commentRss>
		<slash:comments>28</slash:comments>
		</item>
		<item>
		<title>5e speculative background images</title>
		<link>http://www.stevesouders.com/blog/2010/02/12/5e-speculative-background-images/</link>
		<comments>http://www.stevesouders.com/blog/2010/02/12/5e-speculative-background-images/#comments</comments>
		<pubDate>Sat, 13 Feb 2010 02:09:27 +0000</pubDate>
		<dc:creator>Steve Souders</dc:creator>
				<category><![CDATA[Chrome]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[IE8]]></category>
		<category><![CDATA[Internet Explorer]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[browsers]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Safari]]></category>

		<guid isPermaLink="false">http://www.stevesouders.com/blog/?p=911</guid>
		<description><![CDATA[This is the fifth of five quick posts about some browser quirks that     have come up in the last few weeks.
Chrome and Safari start downloading background images before all styles are available. If a background image style gets overwritten this may cause wasteful downloads.
Background images are used everywhere: buttons, background wallpaper, [...]]]></description>
			<content:encoded><![CDATA[<p>This is the fifth of five quick posts about some browser quirks that     have come up in the last few weeks.</p>
<p><em>Chrome and Safari start downloading background images before all styles are available. If a background image style gets overwritten this may cause wasteful downloads.</em></p>
<p>Background images are used everywhere: buttons, background wallpaper, rounded corners, etc. You specify a background image in CSS like so:</p>
<pre style="padding-left: 30px;">.bgimage { background-image: url("/images/button1.gif"); }</pre>
<p>Downloading resources is an area for optimizing performance, so it&#8217;s important to understand what causes CSS background images to get downloaded. See if you can answer the following questions about button1.gif:</p>
<ol>
<li>Suppose no elements in the page use the class &#8220;bgimage&#8221;. Is button1.gif downloaded?</li>
<li>Suppose an element in the page has the class &#8220;bgimage&#8221; but also has &#8220;display: none&#8221; or &#8220;visibility: hidden&#8221;. Is button1.gif downloaded?</li>
<li>Suppose later in the page a stylesheet gets downloaded and redefines the &#8220;bgimage&#8221; class like this:
<pre style="padding-left: 30px;">.bgimage { background-image: url("/images/button2.gif"); }</pre>
<p>Is button1.gif downloaded?</li>
</ol>
<p>Ready?</p>
<p>The answer to question #1 is &#8220;no&#8221;. If no elements in the page use the rule, then the background image is not downloaded. This is true in all browsers that I&#8217;ve tested.</p>
<p>The answer to question #2 is &#8220;depends on the browser&#8221;. This might be surprising. Firefox 3.6 and Opera 10.10 <em>do not </em>download button1.gif, but the background image <em>is</em> downloaded in IE 8, Safari 4, and Chrome 4. I don&#8217;t have an explanation for this, but I do have a test page: <a href="http://stevesouders.com/tests/hidden-bgimages.php">hidden background images</a>. If you have elements with background images that are hidden initially, you should hold off on creating them until after the visible content in the page is rendered.</p>
<p>The answer to question #3 is &#8220;depends on the browser&#8221;. I find this to be the most interesting behavior to investigate. According to the cascading behavior of CSS, the latter definition of the &#8220;bgimage&#8221; class should cause the background-image style to use button2.gif. And in all the major browsers this is exactly what happens. But Safari 4 and Chrome 4 are a little more aggressive about fetching background images. They download button1.gif on the speculation that the background-image property won&#8217;t be overwritten, and then later download button2.gif when it is overwritten. Here&#8217;s the test page: <a href="http://stevesouders.com/tests/speculative-bgimages.php">speculative background images</a>.</p>
<p>When my officemate, Steve Lamm, pointed out this behavior to me, my first reaction was &#8220;that&#8217;s wasteful!&#8221; I love prefetching, but I&#8217;m not a big fan of most prefetching implementations because they&#8217;re too aggressive &#8211; they err too far on the side of downloading resources that never get used. After my initial reaction, I thought about this some more. How frequently would this speculative background image downloading be wasteful? I went on a search and couldn&#8217;t find any popular web site that overwrote the background-image style. Not one. I&#8217;m not saying pages like this don&#8217;t exist, I&#8217;m just saying it&#8217;s very atypical.</p>
<p>On the other hand, this speculative downloading of background images can really help performance and the user&#8217;s perception of page speed. Many web sites have multiple stylesheets. If background images don&#8217;t start downloading until all stylesheets are done loading, the page takes longer to render. Safari and Chrome&#8217;s behavior of downloading a background image as soon as an element needs it, even if one or more stylesheets are still downloading, is a nice performance optimization.</p>
<p>That&#8217;s a nice way to finish the week. Next week: my Browser Performance Wishlist.</p>
<p style="margin-bottom: 0;">The five posts in this series are:</p>
<ul style="margin-top: 0;">
<li><a href="http://www.stevesouders.com/blog/2010/02/10/5a-missing-schema-double-download/">5a Missing schema double download</a></li>
<li><a href="http://www.stevesouders.com/blog/2010/02/10/5b-document-write-scripts-block-in-firefox/">5b document.write scripts block in Firefox</a></li>
<li><a href="http://www.stevesouders.com/blog/2010/02/11/mediaprint-stylesheets/">5c media=print stylesheets</a></li>
<li><a href="http://www.stevesouders.com/blog/2010/02/12/5d-dynamic-stylesheets/">5d dynamic stylesheets</a></li>
<li><a href="http://www.stevesouders.com/blog/2010/02/12/5e-speculative-background-images/">5e speculative background images</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.stevesouders.com/blog/2010/02/12/5e-speculative-background-images/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>5d dynamic stylesheets</title>
		<link>http://www.stevesouders.com/blog/2010/02/12/5d-dynamic-stylesheets/</link>
		<comments>http://www.stevesouders.com/blog/2010/02/12/5d-dynamic-stylesheets/#comments</comments>
		<pubDate>Fri, 12 Feb 2010 09:13:48 +0000</pubDate>
		<dc:creator>Steve Souders</dc:creator>
				<category><![CDATA[IE8]]></category>
		<category><![CDATA[Internet Explorer]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[browsers]]></category>
		<category><![CDATA[dhtml]]></category>
		<category><![CDATA[fouc]]></category>
		<category><![CDATA[stylesheets]]></category>

		<guid isPermaLink="false">http://www.stevesouders.com/blog/?p=901</guid>
		<description><![CDATA[This is the fourth of five quick posts about some browser quirks that    have come up in the last few weeks.
You can avoid blocking rendering in IE if you load stylesheets using DHTML and setTimeout.
A few weeks ago I had a meeting with a company that makes a popular widget. One technique [...]]]></description>
			<content:encoded><![CDATA[<p>This is the fourth of five quick posts about some browser quirks that    have come up in the last few weeks.</p>
<p><em>You can avoid blocking rendering in IE if you load stylesheets using DHTML and setTimeout.</em></p>
<p>A few weeks ago I had a meeting with a company that makes a popular widget. One technique they used to reduce their widget&#8217;s impact on the main page was to load a stylesheet dynamically, something like this:</p>
<pre style="margin-left: 20px; margin-right: 20px; background: #F0F0F0; padding: 8px;">var link = document.createElement('link');
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = '/main.css';
document.getElementsByTagName('head')[0].appendChild(link);</pre>
<p>Most of my attention for the past year has been on loading scripts dynamically to avoid blocking downloads. I haven&#8217;t focused on loading stylesheets dynamically. When it comes to stylesheets, blocking downloads isn&#8217;t an issue &#8211; stylesheets don&#8217;t block downloads (except in Firefox 2.0). The thing to worry about when downloading stylesheets is that IE blocks rendering until all stylesheets are downloaded<sup>1</sup>, and other browsers might experience a <a href="http://weblogs.mozillazine.org/hyatt/archives/2004_05.html#005496">Flash  Of Unstyled Content (FOUC)</a>.</p>
<p>FOUC isn&#8217;t a concern for this widget &#8211; the rules in the dynamically-loaded stylesheet only apply to the widget, and the widget hasn&#8217;t been created yet so nothing can flash. If the point of loading the stylesheet dynamically is to not mess with the containing page, we have to make sure dynamic stylesheets don&#8217;t block the page from rendering in IE.</p>
<p>I created the <a href="http://stevesouders.com/tests/dhtml-stylesheet.php">DHTML stylesheet</a> example to show what happens. The page loads a stylesheet dynamically. The stylesheet is configured to take 4 seconds to download. If you load the page in Internet Explorer the page is blank for 4 seconds. In order to decouple the stylesheet load from page rendering, the DHTML code has to be invoked using setTimeout. That&#8217;s what I do in the <a href="http://stevesouders.com/tests/dhtml-stylesheet-settimeout.php">DHTML + setTimeout stylesheet</a> test page. This works. The page renders immediately while the stylesheet is downloaded in the background.</p>
<p>This technique is applicable when you have stylesheets that you want to load in the page but the stylesheet&#8217;s rules don&#8217;t apply to any DOM elements in the page currently. This is a pretty small use case. It makes sense for widgets or pages that have DHTML features that aren&#8217;t invoked until after the page has loaded. If you find yourself in that situation, you can use this technique to avoid the blank white screen in IE.</p>
<p style="margin-bottom: 0;">The five posts in this series are:</p>
<ul style="margin-top: 0;">
<li><a href="http://www.stevesouders.com/blog/2010/02/10/5a-missing-schema-double-download/">5a Missing schema double download</a></li>
<li><a href="http://www.stevesouders.com/blog/2010/02/10/5b-document-write-scripts-block-in-firefox/">5b document.write scripts block in Firefox</a></li>
<li><a href="http://www.stevesouders.com/blog/2010/02/11/mediaprint-stylesheets/">5c media=print stylesheets</a></li>
<li><a href="http://www.stevesouders.com/blog/2010/02/12/5d-dynamic-stylesheets/">5d dynamic stylesheets</a></li>
<li><a href="http://www.stevesouders.com/blog/2010/02/12/5e-speculative-background-images/">5e speculative background images</a></li>
</ul>
<table style="font-size: 0.8em; margin-top: 20px;" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td style="vertical-align: top; padding-right: 4px;"><sup>1</sup></td>
<td>Simple test pages may not reproduce this problem. My testing shows that you need a script (inline or external) above the stylesheet, or two or more stylesheets for rendering to be blocked. If your page has only one stylesheet and no SCRIPT tags, you might not experience this issue.</td>
</tr>
</tbody>
</table>
]]></content:encoded>
			<wfw:commentRss>http://www.stevesouders.com/blog/2010/02/12/5d-dynamic-stylesheets/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>5c media=print stylesheets</title>
		<link>http://www.stevesouders.com/blog/2010/02/11/mediaprint-stylesheets/</link>
		<comments>http://www.stevesouders.com/blog/2010/02/11/mediaprint-stylesheets/#comments</comments>
		<pubDate>Fri, 12 Feb 2010 01:27:48 +0000</pubDate>
		<dc:creator>Steve Souders</dc:creator>
				<category><![CDATA[IE8]]></category>
		<category><![CDATA[Internet Explorer]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[browsers]]></category>
		<category><![CDATA[fouc]]></category>
		<category><![CDATA[stylesheet]]></category>

		<guid isPermaLink="false">http://www.stevesouders.com/blog/?p=892</guid>
		<description><![CDATA[This is the third of five quick posts about some browser quirks that   have come up in the last few weeks.
Stylesheets set with media=&#8221;print&#8221; still block rendering in Internet Explorer.
A few weeks ago a friend at a top web company pinged me about a possible bug in Page Speed and YSlow. Both tools [...]]]></description>
			<content:encoded><![CDATA[<p>This is the third of five quick posts about some browser quirks that   have come up in the last few weeks.</p>
<p><em>Stylesheets set with media=&#8221;print&#8221; still block rendering in Internet Explorer.</em></p>
<p>A few weeks ago a friend at a top web company pinged me about a possible bug in <a href="http://code.google.com/speed/page-speed/">Page Speed</a> and <a href="http://developer.yahoo.com/yslow/">YSlow</a>. Both tools were complaining about stylesheets he placed at the bottom of his page, an obvious violation of my <a href="http://developer.yahoo.net/blog/archives/2007/07/high_performanc_4.html">put stylesheets at the top</a> rule from <a href="http://www.amazon.com/High-Performance-Web-Sites-Essential/dp/0596529309">High  Performance Web Sites</a>. The reasoning behind this rule is that Internet Explorer won&#8217;t start rendering the page until all stylesheets are downloaded<sup>1</sup>, and other browsers might produce the <a href="http://weblogs.mozillazine.org/hyatt/archives/2004_05.html#005496">Flash Of Unstyled Content (FOUC)</a>. It&#8217;s best to put stylesheets at the top so they get downloaded as soon as possible.</p>
<p>His reason for putting these stylesheets at the bottom was that they were specified with <code>media="print"</code>. Since these stylesheets weren&#8217;t going to be used to render the current page, he wanted to load them last so that other more important resources could get downloaded sooner. Going back to the reasons for the &#8220;put stylesheets at the top&#8221; rule, he wouldn&#8217;t have to worry about FOUC (the stylesheets wouldn&#8217;t be applied to the current page). But would he have to worry about IE blocking the page from rendering? Time for a test page.</p>
<p>The <a href="http://stevesouders.com/tests/mediaprint.php">media=print stylesheets</a> test page contains one stylesheet at the bottom with <code>media="print"</code>. This stylesheet is configured to take 4 seconds to download. If you view this page in Internet Explorer you&#8217;ll see that rendering is indeed blocked for 4 seconds (tested on IE 6, 7, &amp; 8).</p>
<p>I&#8217;m surprised browsers haven&#8217;t gotten to the point where they skip downloading stylesheets for a different media type than the current one. I&#8217;ve asked some web devs but no one can think of a good reason for doing this. In the meantime, even if you have stylesheets with <code>media="print"</code> you might want to follow the advice of <a href="http://code.google.com/speed/page-speed/">Page Speed</a> and <a href="http://developer.yahoo.com/yslow/">YSlow</a> and put them in the document HEAD. Or you could try loading them dynamically. That&#8217;s the topic I&#8217;ll cover in my next blog post.</p>
<p style="margin-bottom: 0;">The five posts in this series are:</p>
<ul style="margin-top: 0;">
<li><a href="http://www.stevesouders.com/blog/2010/02/10/5a-missing-schema-double-download/">5a Missing schema double download</a></li>
<li><a href="http://www.stevesouders.com/blog/2010/02/10/5b-document-write-scripts-block-in-firefox/">5b document.write scripts block in Firefox</a></li>
<li><a href="http://www.stevesouders.com/blog/2010/02/11/mediaprint-stylesheets/">5c media=print stylesheets</a></li>
<li><a href="http://www.stevesouders.com/blog/2010/02/12/5d-dynamic-stylesheets/">5d dynamic stylesheets</a></li>
<li><a href="http://www.stevesouders.com/blog/2010/02/12/5e-speculative-background-images/">5e speculative background images</a></li>
</ul>
<table style="font-size: 0.8em;" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td style="vertical-align: top; padding-right: 4px;"><sup>1</sup></td>
<td>Simple test pages may not reproduce this problem. My testing shows that you need a script (inline or external) above the stylesheet, or two or more stylesheets for rendering to be blocked. If your page has only one stylesheet and no SCRIPT tags, you might not experience this issue.</td>
</tr>
</tbody>
</table>
]]></content:encoded>
			<wfw:commentRss>http://www.stevesouders.com/blog/2010/02/11/mediaprint-stylesheets/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>5a Missing schema double download</title>
		<link>http://www.stevesouders.com/blog/2010/02/10/5a-missing-schema-double-download/</link>
		<comments>http://www.stevesouders.com/blog/2010/02/10/5a-missing-schema-double-download/#comments</comments>
		<pubDate>Thu, 11 Feb 2010 01:12:38 +0000</pubDate>
		<dc:creator>Steve Souders</dc:creator>
				<category><![CDATA[IE8]]></category>
		<category><![CDATA[Internet Explorer]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[protocol]]></category>

		<guid isPermaLink="false">http://www.stevesouders.com/blog/?p=877</guid>
		<description><![CDATA[This is the first of five quick posts about some browser quirks that have come up in the last few weeks.
Internet Explorer 7 &#38; 8 will download stylesheets twice if the http(s) protocol is missing.
If you have an HTTPS page that loads resources with &#8220;http://&#8221; in the URL, IE halts the download and displays an [...]]]></description>
			<content:encoded><![CDATA[<p>This is the first of five quick posts about some browser quirks that have come up in the last few weeks.</p>
<p><em>Internet Explorer 7 &amp; 8 will download stylesheets twice if the http(s) protocol is missing.</em></p>
<p>If you have an HTTPS page that loads resources with &#8220;http://&#8221; in the URL, IE halts the download and <a href="http://blog.httpwatch.com/2009/04/23/fixing-the-ie-8-warning-do-you-want-to-view-only-the-webpage-content-that-was-delivered-securely/">displays an error dialog</a>. This is called <em>mixed content</em> and should be avoided. How should developers code their URLs to avoid this problem? You could do it on the backend in your HTML template language. But a practice that is getting wider adoption is protocol relative URLs.</p>
<p>A <em>protocol relative URL</em> doesn&#8217;t contain a protocol. For example,</p>
<div style="margin-left: 20px;"><code>http://stevesouders.com/images/book-84x110.jpg</code></div>
<p>becomes</p>
<div style="margin-left: 20px;"><code>//stevesouders.com/images/book-84x110.jpg</code></div>
<p>Browsers substitute the protocol of the page itself for the resource&#8217;s missing protocol. Problem solved! In fact, today&#8217;s <a href="http://blog.httpwatch.com/">HttpWatch Blog</a> posted about this: <a href="http://blog.httpwatch.com/2010/02/10/using-protocol-relative-urls-to-switch-between-http-and-https/">Using  Protocol Relative URLs to Switch between HTTP and HTTPS</a>.</p>
<p>However, if you try this in Internet Explorer 7 and 8 you&#8217;ll see that stylesheets specified with a protocol relative URL are downloaded twice. Hard to believe, but true. My officemate, Steve Lamm, discovered this when looking at the new <a href="http://www.google.com/phone/">Nexus One Phone page</a>. That page fetches a stylesheet like this:</p>
<div style="margin-left: 20px;"><code>&lt;link type="text/css" rel="stylesheet" href="//www.google.com/phone/static/2496921881-SiteCss.css"&gt;</code></div>
<p>Notice there&#8217;s no protocol. If you load this page in Internet Explorer 7 and 8 the waterfall chart (nicely generated by <a href="http://www.httpwatch.com/">HttpWatch</a>) looks like this:</p>
<p><img title="stylesheet is download twice" src="http://stevesouders.com/images/schema-double.png" alt="" width="615" height="115" /></p>
<p>Notice <code>2496921881-SiteCss.css</code> is downloaded twice, and each time it&#8217;s a 200 response, so it&#8217;s not being read from cache.</p>
<p>It turns out this only happens with stylesheets. The <a href="http://stevesouders.com/tests/schema-double.php">Missing schema, double download</a> test page I created contains a stylesheet, an image, and a script that all have protocol relative URLs pointing to <code>1.cuzillion.com</code>. The stylesheet is downloaded twice, but the image and script are only downloaded once. I added another stylesheet from <code>2.cuzillion.com</code> that has a full URL (i.e., it starts with &#8220;http:&#8221;). This stylesheet is only downloaded once.</p>
<p>Developers should avoid using protocol relative URLs for stylesheets if they want their pages to be as fast as possible in Internet Explorer 7 &amp; 8.</p>
<p style="margin-bottom: 0;">The five posts in this series are:</p>
<ul style="margin-top: 0;">
<li><a href="http://www.stevesouders.com/blog/2010/02/10/5a-missing-schema-double-download/">5a Missing schema double download</a></li>
<li><a href="http://www.stevesouders.com/blog/2010/02/10/5b-document-write-scripts-block-in-firefox/">5b document.write scripts block in Firefox</a></li>
<li><a href="http://www.stevesouders.com/blog/2010/02/11/mediaprint-stylesheets/">5c media=print stylesheets</a></li>
<li><a href="http://www.stevesouders.com/blog/2010/02/12/5d-dynamic-stylesheets/">5d dynamic stylesheets</a></li>
<li><a href="http://www.stevesouders.com/blog/2010/02/12/5e-speculative-background-images/">5e speculative background images</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.stevesouders.com/blog/2010/02/10/5a-missing-schema-double-download/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Browser script loading roundup</title>
		<link>http://www.stevesouders.com/blog/2010/02/07/browser-script-loading-roundup/</link>
		<comments>http://www.stevesouders.com/blog/2010/02/07/browser-script-loading-roundup/#comments</comments>
		<pubDate>Sun, 07 Feb 2010 08:12:23 +0000</pubDate>
		<dc:creator>Steve Souders</dc:creator>
				<category><![CDATA[Chrome]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[IE8]]></category>
		<category><![CDATA[Internet Explorer]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[browsers]]></category>
		<category><![CDATA[browserscope]]></category>
		<category><![CDATA[Opera]]></category>
		<category><![CDATA[Safari]]></category>

		<guid isPermaLink="false">http://www.stevesouders.com/blog/?p=849</guid>
		<description><![CDATA[How are browsers doing when it comes to parallel script loading?
Back in the days of IE7 and Firefox 2.0, no browser loaded scripts in parallel with other resources. Instead, these older browsers would block all subsequent resource requests until the script was received, parsed, and executed. Here&#8217;s how the HTTP requests look when this blocking [...]]]></description>
			<content:encoded><![CDATA[<p><em>How are browsers doing when it comes to parallel script loading?</em></p>
<p>Back in the days of IE7 and Firefox 2.0, no browser loaded scripts in parallel with other resources. Instead, these older browsers would block all subsequent resource requests until the script was received, parsed, and executed. Here&#8217;s how the HTTP requests look when this blocking occurs in older browsers:</p>
<div style="margin-left: 40px;"><img class="alignnone" title="Scripts block parallel downloads in older browsers." src="http://stevesouders.com/efws/images/scripts-block.gif" border="1" alt="" width="402" height="104" /></div>
<p><a href="http://stevesouders.com/cuzillion/?ex=10008&amp;title=Scripts+Block+Downloads">The test page</a> that generated this waterfall chart has six HTTP requests:</p>
<ol>
<li>the HTML document</li>
<li>the 1st script &#8211; 2 seconds to download, 2 seconds to execute</li>
<li>the 2nd script &#8211; 2 seconds to download, 2 seconds to execute</li>
<li>an image &#8211; 1 second to download</li>
<li>a stylesheet- 1 second to download</li>
<li>an iframe &#8211; 1 second to download</li>
</ol>
<p>The figure above shows how the scripts block each other and block the image, stylesheet, and iframe, as well. The image, stylesheet, and iframe download in parallel with each other, but not until the scripts are finished downloading sequentially.</p>
<p>The likely reason scripts were downloaded sequentially in older browsers was to preserve execution order. This is critical when code in the 2nd script depends on symbols defined in the 1st script. Preserving execution order avoids undefined symbol errors. But the missed opportunity is obvious &#8211; while the browser is downloading the first script and guaranteeing to execute it first, it could be downloading the other four resources in parallel.</p>
<p><em>Thankfully, newer browsers now load scripts in parallel!</em></p>
<p>This is a big win for today&#8217;s web apps that often contain 100K+ of JavaScript split across multiple files. Loading the same <a href="http://stevesouders.com/cuzillion/?ex=10008&amp;title=Scripts+Block+Downloads">test page</a> in IE8, Firefox 3.6, Chrome 4, and Safari 4 produces an HTTP waterfall chart like this:</p>
<div style="margin-left: 40px;"><img class="alignnone" title="Scripts load in parallel in newer browsers" src="http://stevesouders.com/efws/images/scripts-block-ie8.gif" border="1" alt="" width="319" height="104" /></div>
<p>Things look a lot better, but not as good as they should be. In this  case, IE8 loads the two scripts and stylesheet in parallel, but the  image and iframe are blocked. All of the newer browsers have similar  limitations with regard to the extent to which they load scripts in  parallel with other types of resources. This <a href="http://www.browserscope.org/?category=network&amp;v=2&amp;ua=Chrome%204,Firefox%203.0,Firefox%203.5,Firefox%203.6,IE%206,IE%208,Opera%2010.10,Safari%203.2,Safari%204.0">table  from Browserscope</a> shows where we are and the progress made to get  to this point. The recently added &#8220;Compare&#8221; button added to <a href="http://www.browserscope.org/">Browserscope</a> made it easy to   generate this historical view.</p>
<div style="margin-left: 40px;"><a href="http://www.browserscope.org/?category=network&amp;v=2&amp;ua=Chrome%204,Firefox%203.0,Firefox%203.5,Firefox%203.6,IE%206,IE%208,Opera%2010.10,Safari%203.2,Safari%204.0"><img class="alignnone" title="Browserscope parallel script loading test results" src="http://stevesouders.com/images/browserscope-parallel-scripts.png" border="0" alt="" width="438" height="343" /></a></div>
<p>While downloading scripts, IE8 still blocks on images and iframes.  Chrome 4, Firefox 3.6, and Safari 4 block on iframes. Opera 10.10 blocks  on all resource types. I&#8217;m confident parallel script loading will  continue to improve based on the great progress made in the last batch  of browsers. Let&#8217;s keep our eyes on the next browsers to see if things improve even more.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.stevesouders.com/blog/2010/02/07/browser-script-loading-roundup/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Speed Tracer &#8211; visibility into the browser</title>
		<link>http://www.stevesouders.com/blog/2009/12/10/speed-tracer/</link>
		<comments>http://www.stevesouders.com/blog/2009/12/10/speed-tracer/#comments</comments>
		<pubDate>Thu, 10 Dec 2009 15:46:22 +0000</pubDate>
		<dc:creator>Steve Souders</dc:creator>
				<category><![CDATA[Chrome]]></category>
		<category><![CDATA[Firebug]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Internet Explorer]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[browsers]]></category>
		<category><![CDATA[crossfire]]></category>
		<category><![CDATA[dynatrace]]></category>
		<category><![CDATA[pagetest]]></category>
		<category><![CDATA[profiler]]></category>
		<category><![CDATA[speed tracer]]></category>
		<category><![CDATA[web inspector]]></category>
		<category><![CDATA[webpagetest]]></category>

		<guid isPermaLink="false">http://www.stevesouders.com/blog/?p=792</guid>
		<description><![CDATA[Is it just me, or does anyone else think Google&#8217;s on fire lately, lighting up the world of web performance? Quick review of news from the past two weeks:

timeline and heap profiler added to Chrome Dev Tools
Google Analytics publishes async script loading pattern
latency and Page Speed recommendations added to Webmaster Tools
deep dive into what makes [...]]]></description>
			<content:encoded><![CDATA[<p>Is it just me, or does anyone else think Google&#8217;s on fire lately, lighting up the world of web performance? Quick review of news from the past two weeks:</p>
<ul>
<li><a href="http://blog.chromium.org/2009/11/update-for-google-chromes-developer.html">timeline and heap profiler added to Chrome Dev Tools</a></li>
<li><a href="http://googlecode.blogspot.com/2009/12/google-analytics-launches-asynchronous.html">Google Analytics publishes async script loading pattern</a></li>
<li><a href="http://googlewebmastercentral.blogspot.com/2009/12/how-fast-is-your-site.html">latency and Page Speed recommendations added to Webmaster Tools</a></li>
<li><a href="http://blog.chromium.org/2009/12/technically-speaking-what-makes-google.html">deep dive into what makes Chrome (and browsers in general) fast</a></li>
<li><a href="http://googlecode.blogspot.com/2009/12/introducing-google-public-dns-new-dns.html">Google Public DNS launched</a></li>
<li>and now&#8230; <a href="http://googleblog.blogspot.com/2009/12/faster-apps-for-faster-web-introducing.html">the release of Speed Tracer</a></li>
</ul>
<p>Speed Tracer was my highlight from last night&#8217;s <a href="http://code.google.com/campfire/">Google Campfire One</a>. The event celebrated the release of <a href="http://googlecode.blogspot.com/2009/12/google-web-toolkit-20-now-with-speed.html">GWT 2.0</a>. Performance and &#8220;faster&#8221; were emphasized again and again throughout the evening&#8217;s presentations (I love that). GWT&#8217;s new <a href="http://code.google.com/webtoolkit/doc/latest/DevGuideCodeSplitting.html">code splitting capabilities</a> are great for performance, but Speed Tracer easily wowed the audience &#8211; including me. In this post, I&#8217;ll describe what I like about Speed Tracer, what I hope to see added next, and then I&#8217;ll step back and talk about the state of performance profilers.</p>
<h2>Getting started with Speed Tracer</h2>
<p>Some quick notes about Speed Tracer:</p>
<ul>
<li>It&#8217;s a Chrome extension, so it only runs in Chrome. (Chrome extensions is yet another <a href="http://blog.chromium.org/2009/12/extensions-beta-launched-with-over-300.html">announcement</a> this week.)</li>
<li>It&#8217;s written in <a href="http://code.google.com/webtoolkit/">GWT 2.0</a>.</li>
<li>It works on all web sites, even sites that don&#8217;t use GWT.</li>
</ul>
<p>The Speed Tracer <a href="http://code.google.com/webtoolkit/speedtracer/get-started.html">getting started page</a> provides the details for installation. You have to be on the <a href="http://dev.chromium.org/getting-involved/dev-channel">Chrome dev channel</a>. Installing Speed Tracer adds a green stopwatch to the toolbar. Clicking on the icon starts Speed Tracer in a separate Chrome window. As you surf sites in the original window, the performance information is shown in the Speed Tracer window.</p>
<p><img class="alignnone" title="Speed Tracer installed" src="http://stevesouders.com/images/speed-tracer-installed.png" alt="" width="534" height="196" /></p>
<h2>Beautiful visibility</h2>
<p>When it comes to optimizing performance, developers have long been working in the dark. Without the ability to measure JavaScript execution, page layout, reflows, and HTML parsing, it&#8217;s not possible to optimize the pain points of today&#8217;s web apps. Speed Tracer gives developers visibility into these parts of page loading via the <em>Sluggishness view</em>, as shown here. (Click on the figure to see a full screen view.) Not only is this kind of visibility great, but the display is just, well, beautiful. Good UI and dev tools don&#8217;t often intersect, but when they do it makes development that much easier and more enjoyable.</p>
<p><a href="http://stevesouders.com/images/speed-tracer-sluggishness-812x622.png"><img class="alignnone" title="Speed Tracer sluggishness graph" src="http://stevesouders.com/images/speed-tracer-sluggishness-394x485.png" alt="" width="394" height="485" /></a></p>
<p>Speed Tracer also has a <em>Network view</em>, with the requisite waterfall chart of HTTP requests. Performance hints are built into the tool flagging issues such as bad cache headers, exceedingly long responses, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=355567">Mozilla cache hash collision</a>, too many reflows, and uncompressed responses. Speed Tracer also supports saving and reloading the profiled information. This is extremely useful when working on bugs or analyzing performance with other team members.</p>
<h2>Feature requests</h2>
<p>I&#8217;m definitely going to be using Speed Tracer. For a first version, it&#8217;s extremely feature rich and robust. There are a few enhancements that will make it even stronger:</p>
<ul>
<li><em>overall pie chart</em> &#8211; The &#8220;breakdown by time&#8221; for phases like script evaluation and layout are available for segments within a page load. As a starting point, I&#8217;d like to see the breakdown for the entire page. When drilling down on a specific load segment, this detail is great. But having overall stats will give developers a clue where they should focus most of their attention.</li>
<li><em>network timing</em> &#8211; Similar to the <a href="http://www.softwareishard.com/blog/firebug/firebug-http-time-monitor/">issues</a> I discovered in Firebug Net Panel, long-executing JavaScript in the main page blocks the network monitor from accurately measuring the duration of HTTP requests. This will likely require changes to WebKit to record event times in the events themselves, as was done in <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=488270">the fix for Firefox</a>.</li>
<li><em>.HAR support</em> &#8211; Being able to save Speed Tracer&#8217;s data to file and share it is great. Recently, <a href="http://www.softwareishard.com/blog/firebug/http-archive-specification/">Firebug</a>, <a href="http://blog.httpwatch.com/2009/10/19/httpwatch-version-62-supports-data-exchange-with-firebug/">HttpWatch</a>, and <a href="http://www.debugbar.com/?langage=en">DebugBar</a> have all launched support for the <a href="http://groups.google.com/group/firebug-working-group/web/http-tracing---export-format">HTTP Archive file format</a> I helped create. The format is extensible, so I hope to see Speed Tracer support the .HAR file format soon. Being able to share performance information across tools and browsers is a necessary next step. That&#8217;s a good segue&#8230;</li>
</ul>
<h2>Developers need more</h2>
<p>Three years ago, there was only one tool for profiling web pages: <a href="http://getfirebug.com/">Firebug</a>. Developers love working in Firefox, but sometimes you just have to profile in Internet Explorer. Luckily, over the last year we&#8217;ve seen some good profilers come out for IE including <a href="http://msfast.myspace.com/">MSFast</a> , <a href="http://sourceforge.net/apps/mediawiki/pagetest/">AOL Pagetest</a>, <a href="http://webpagetest.org/">WebPagetest.org</a>, and <a href="http://ajax.dynatrace.com/pages/">dynaTrace Ajax Edition</a>. DynaTrace&#8217;s tool is the most recent addition, and has great visibility similar to Speed Tracer, as well as JavaScript debugging capabilities. There have been <a href="http://webkit.org/blog/829/web-inspector-updates/">great enhancements to Web Inspector</a>, and the Chrome team has built on top of that adding <a href="http://blog.chromium.org/2009/11/update-for-google-chromes-developer.html">timeline and memory profiling to Chrome</a>. And now Speed Tracer is out and bubbling to the top of the heap.</p>
<p>The obvious question is:</p>
<p style="padding-left: 30px;"><em>Which tool should a developer choose?</em></p>
<p>But the more important question is:</p>
<p style="padding-left: 30px;"><em>Why should a developer have to choose?</em></p>
<p>There are eight performance profilers listed here. None of them work in more than a single browser. I realize web developers are exceedingly intelligent and hardworking, but no one enjoys having to use two different tools for the same task. But that&#8217;s exactly what developers are being asked to do. To be a good developer, you have to be profiling your web site in multiple browsers. By definition, that means you have to install, learn, and update multiple tools. In addition, there are numerous quirks to keep in mind when going from one tool to another. And the features offered are not consistent across tools. It&#8217;s a real challenge to verify that your web app performs well across the major browsers. When pressed, rock star web developers I ask admit they only use one or two profilers &#8211; it&#8217;s just too hard to stay on top of a separate tool for each browser.</p>
<p>This week at <a href="http://addoncon.com/">Add-on-Con</a>, Doug Crockford&#8217;s closing keynote is about <a href="http://addoncon.com/sessionkeynotes.html">the Future of the Web Browser</a>. He&#8217;s assembled a panel of representatives from Chrome, Opera, Firefox, and IE. (Safari declined to attend.) My hope is they&#8217;ll discuss the need for a cross-browser extension model. There&#8217;s been progress in building protocols to support remote debugging: <a href="http://groups.google.com/group/webdebugprotocol?hl=en">WebDebugProtocol</a> and <a href="http://getfirebug.com/wiki/index.php/Crossfire">Crossfire</a> in Firefox, <a href="http://dragonfly.opera.com/app/scope-interface/">Scope</a> in Opera, and <a href="http://code.google.com/p/chromedevtools/">ChromeDevTools</a> in Chrome. My hope for 2010 is that we see cross-browser convergence on standards for extensions and remote debugging, so that developers will have a slightly easier path for ensuring their apps are high performance on all browsers.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.stevesouders.com/blog/2009/12/10/speed-tracer/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Who&#8217;s not getting gzip?</title>
		<link>http://www.stevesouders.com/blog/2009/11/11/whos-not-getting-gzip/</link>
		<comments>http://www.stevesouders.com/blog/2009/11/11/whos-not-getting-gzip/#comments</comments>
		<pubDate>Thu, 12 Nov 2009 06:46:36 +0000</pubDate>
		<dc:creator>Steve Souders</dc:creator>
				<category><![CDATA[HTTP]]></category>
		<category><![CDATA[Internet Explorer]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Velocity]]></category>
		<category><![CDATA[browsers]]></category>
		<category><![CDATA[compression]]></category>
		<category><![CDATA[gzip]]></category>
		<category><![CDATA[proxy]]></category>

		<guid isPermaLink="false">http://www.stevesouders.com/blog/?p=704</guid>
		<description><![CDATA[The article Use compression to make the web faster from the Google Code Blog contains some interesting information on why modern browsers that support compression don&#8217;t get compressed responses in daily usage. The culprit?
anti-virus software, browser bugs, web proxies, and misconfigured web servers.  The first three modify the web request so that the web server [...]]]></description>
			<content:encoded><![CDATA[<p>The article <a href="http://googlecode.blogspot.com/2009/11/use-compression-to-make-web-faster.html">Use compression to make the web faster</a> from the Google Code Blog contains some interesting information on why modern browsers that support compression don&#8217;t get compressed responses in daily usage. The culprit?</p>
<blockquote><p>anti-virus software, browser bugs, web proxies, and misconfigured web servers.  The first three modify the web request so that the web server does not know that the browser can uncompress content. Specifically, they remove or mangle the Accept-Encoding header that is normally sent with every request.</p></blockquote>
<p>This is hard to believe, but it&#8217;s true. Tony Gentilcore covers the full story in the chapter he wrote called &#8220;Going Beyond Gzipping&#8221; in <a href="http://www.amazon.com/Even-Faster-Web-Sites-Performance/dp/0596522304">my most recent book</a>, including some strategies for correcting and working around the problem. (Check out Tony&#8217;s <a href="http://assets.en.oreilly.com/1/event/29/Beyond%20Gzipping%20Presentation.pdf">slides from Velocity 2009</a>.) According to Tony:</p>
<blockquote><p>a large web site in the United States should expect roughly 15% of visitors don&#8217;t indicate gzip compression support.</p></blockquote>
<p>This blog post from Arvind Jain and Jason Glasgow contains additional information, including:</p>
<ul>
<li>Users suffering from this problem experience a Google Search page that is 25% slower &#8211; 1600ms for compressed content versus 2000ms for uncompressed.</li>
<li>Google Search was able to force the content to be compressed (even though the browser didn&#8217;t request it), and improved page load times by 300ms.</li>
<li>Internet Explorer 6 downgrades to HTTP/1.0 and drops the Accept-Encoding request header when behind a proxy. For Google Search, 36% of the search results sent without compression were for IE6.</li>
</ul>
<p>Is there something about your browser, proxy, or anti-virus software that&#8217;s preventing you from getting compressed content and slowing you down 25%? Test it out by visiting the <a id="dbh7" title="brower compression test page" href="http://www.browserscope.org/network/test?test_key=gzip">browser compression test page</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.stevesouders.com/blog/2009/11/11/whos-not-getting-gzip/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>
