<?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; EFWS</title>
	<atom:link href="http://www.stevesouders.com/blog/category/efws/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.stevesouders.com/blog</link>
	<description>Essential knowledge for making your web pages faster.</description>
	<lastBuildDate>Thu, 02 Feb 2012 01:27:44 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Render first. JS second.</title>
		<link>http://www.stevesouders.com/blog/2010/09/30/render-first-js-second/</link>
		<comments>http://www.stevesouders.com/blog/2010/09/30/render-first-js-second/#comments</comments>
		<pubDate>Thu, 30 Sep 2010 18:10:39 +0000</pubDate>
		<dc:creator>Steve Souders</dc:creator>
				<category><![CDATA[browsers]]></category>
		<category><![CDATA[EFWS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[asynchronous]]></category>
		<category><![CDATA[Crockford]]></category>
		<category><![CDATA[defer]]></category>
		<category><![CDATA[node.js]]></category>
		<category><![CDATA[Opera]]></category>
		<category><![CDATA[progressive enhancement]]></category>

		<guid isPermaLink="false">http://www.stevesouders.com/blog/?p=1512</guid>
		<description><![CDATA[Let me start with the takeaway point: The key to creating a fast user experience in today&#8217;s web sites is to render the page as quickly as possible. To achieve this JavaScript loading and execution has to be deferred. I&#8217;m in the middle of several big projects so my blogging rate is down. But I [...]]]></description>
			<content:encoded><![CDATA[<p>Let me start with the takeaway point:</p>
<p style="padding-left: 30px;"><em>The key to creating a fast user experience in today&#8217;s web sites is to render the page as quickly as possible. To achieve this JavaScript loading and execution has to be deferred.</em></p>
<p>I&#8217;m in the middle of several <strong>big</strong> projects so my blogging rate is down. But I got an email today about asynchronous JavaScript loading and execution. I started to type up my lengthy response and remembered one of those tips for being more productive: &#8220;type shorter emails &#8211; no one reads long emails anyway&#8221;. That just doesn&#8217;t resonate with me. I like typing long emails. I love going into the details. But, I agree that an email response that only a few people might read is not the best investment of time. So I&#8217;m writing up my response here.</p>
<p>It took me months to research and write the &#8220;Loading Scripts Without Blocking&#8221; chapter from <a href="http://www.amazon.com/Even-Faster-Web-Sites-Performance/dp/0596522304">Even Faster Web Sites</a>. <em>Months for a single chapter!</em> I wasn&#8217;t the first person to do async script loading &#8211; I noticed it on <a href="http://msn.com/">MSN</a> way before I started that chapter &#8211; but that work paid off. There has been more research on async script loading from folks like <a href="http://www.stevesouders.com/blog/2009/09/26/mobile-gmail-and-async-script-loading/">Google</a>, <a href="http://www.facebook.com/notes/facebook-engineering/bigpipe-pipelining-web-pages-for-high-performance/389414033919">Facebook</a> and <a href="http://en.oreilly.com/velocity2010/public/schedule/detail/13070">Meebo</a>. Most JavaScript frameworks have async script loading features &#8211; two examples are <a href="http://developer.yahoo.com/yui/yuiloader/">YUI</a> and <a href="http://labjs.com/">LABjs</a>. And 8 of today&#8217;s Alexa Top 10 US sites use advanced techniques to load scripts without blocking: Google, Facebook, Yahoo!, YouTube, Amazon, Twitter, Craigslist(!), and Bing. Yay!</p>
<p>The downside is &#8211; although web sites are doing a better job of <em>downloading</em> scripts without blocking, once those scripts arrive their <em>execution</em> still blocks the page from rendering. Getting the content in front of the user as quickly as possible is the goal. If asynchronous scripts arrive while the page is loading, the browser has to stop rendering in order to parse and execute those scripts. This is the biggest obstacle to creating a fast user experience. I don&#8217;t have scientific results that I can cite to substantiate this claim (that&#8217;s part of the big projects I&#8217;m working on). But anyone who disables JavaScript in their browser can attest that sites feel twice as fast.</p>
<p>My #1 goal right now is to figure out ways that web sites can defer all JavaScript execution until after the page has rendered. Achieving this goal is going to involve advances from multiple camps &#8211; changes to browsers, new web development techniques, and new pieces of infrastructure. I&#8217;ve been talking this up for a year or so. When I mention this idea these are the typical arguments I hear for why this won&#8217;t work:</p>
<div style="margin-left: 20px;">
<div style="font-weight: bold;">JavaScript execution is too complex</div>
<div style="margin-left: 20px; margin-top: 8px;">People point out that: &#8220;JavaScript is a powerful language and developers use it in weird, unexpected ways. Eval and document.write create unexpected dependencies. Blanketedly delaying all JavaScript execution is going to break too many web sites.&#8221;</div>
<div style="margin-left: 20px; margin-top: 8px;">
<p>In response to this argument I point to Opera&#8217;s <a href="http://www.stevesouders.com/blog/2008/09/11/delayed-script-execution-in-opera/">Delayed Script Execution</a> feature. I encourage you to turn it on, surf around, and  try to find a site that breaks. Even sites like Gmail and Facebook work! I&#8217;m sure there are some sites that have problems (perhaps that&#8217;s why this feature is off by default). But if some sites do have problems, how many sites are we talking about? And what&#8217;s the severity of the problems? We definitely don&#8217;t want errors, rendering problems, or loss of ad revenue. Even though Opera has had this feature for over two years (!), I haven&#8217;t heard much discussion about it. Imagine what could happen if significant resources focused on this problem.</p>
</div>
<div style="font-weight: bold; margin-top: 8px;">the page content is actually generated by JS execution</div>
<div style="margin-left: 20px; margin-top: 8px;">Yes, this happens too much IMO. The typical logic is: &#8220;We&#8217;re building an Ajax app so the code to create and manipulate DOM elements has to be written in JavaScript. We could also write that logic on the serverside (in C++, Java, PHP, Python, etc.), but then we&#8217;re maintaining two code bases. Instead, we download everything as JSON and create the DOM in JavaScript on the client &#8211; even for the initial page view.&#8221;</div>
<div style="margin-left: 20px; margin-top: 8px;">If this is the architecture for your web app, then it&#8217;s true &#8211; you&#8217;re going to have to download and execute (a boatload) of JavaScript before the user can see the page. &#8220;But it&#8217;s only for the first page view!&#8221; The first page view is the most important one. &#8220;People start our web app and then leave it running all day, so they only incur the initial page load once.&#8221; Really? Have you verified this? In my experience, users frequently close their tab or browser, or even reboot. &#8220;But then at least they have the scripts in their cache.&#8221; Even so, the scripts still have to be executed and they&#8217;re probably going to have to refetch the JSON responses that include data that could have changed.</div>
<div style="margin-left: 20px; margin-top: 8px;">Luckily, there&#8217;s a strong movement toward server-side JavaScript &#8211; see Doug Crockford&#8217;s <a href="http://www.yuiblog.com/blog/2010/08/30/yui-theater-douglas-crockford-crockford-on-javascript-scene-6-loopage-52-min/">Loopage</a> talk and <a href="http://nodejs.org/">node.js</a>. This would allow that JavaScript code to run on the server, render the DOM, and serve it as HTML to the browser so that it renders quickly without needing JavaScript. The scripts needed for subsequent dynamic Ajaxy behavior can be downloaded lazily after the page has rendered. I expect we&#8217;ll see more solutions to address this particular problem of serving the entire page as HTML, even parts that are rendered using JavaScript</div>
<div style="font-weight: bold; margin-top: 8px;">doing this actually makes the page slower</div>
<div style="margin-left: 20px; margin-top: 8px;">The crux of this argument centers around how you define &#8220;slower&#8221;. The old school way of measuring performance is to look at how long it takes for the window&#8217;s load event to fire. (It&#8217;s so cool to call onload &#8220;old school&#8221;, but a whole series of blog posts on better ways to measure performance is called for.)</div>
<div style="margin-left: 20px; margin-top: 8px;">It is true that delaying script execution could result in larger onload times. Although delaying scripts until after onload is one solution to this problem, it&#8217;s more important to talk about performance yardsticks. These days I focus on how quickly the critical page content renders. Many of Amazon&#8217;s pages, for example, have a lot of content and consequently can have a large onload time, but they do an amazing job of getting the content above-the-fold to render quickly.</div>
<div style="margin-left: 20px; margin-top: 8px;"><a href="http://webpagetest.org/">WebPagetest.org</a>&#8216;s video comparison capabilities help hammer this home. Take a look at this <a href="http://www.youtube.com/watch?v=e9baQckS7As&amp;feature=player_embedded">video of Techcrunch</a>, Mashable, and a few other tech news sites loading. This forces you to look at it from the user&#8217;s perspective. It doesn&#8217;t really matter when the load event fired, what matters is when you can see the page. Reducing render time is more in tune with creating a faster user experience, and delaying JavaScript is key to reducing render time.</div>
<p>What are the next steps?</p>
<ul>
<li>Browsers should look at Opera&#8217;s behavior and implement the SCRIPT <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.html#attr-script-async">ASYNC and DEFER</a> attributes.</li>
<li>Developers should adopt asynchronous script loading techniques and avoid rendering the initial page view with JavaScript on the client.</li>
<li>Third party snippet providers, most notably ads, need to move away from document.write.</li>
</ul>
</div>
<div style="margin-left: 20px;">Rendering first and executing JavaScript second is the key to a faster Web.</div>
]]></content:encoded>
			<wfw:commentRss>http://www.stevesouders.com/blog/2010/09/30/render-first-js-second/feed/</wfw:commentRss>
		<slash:comments>28</slash:comments>
		</item>
		<item>
		<title>Google Analytics goes async</title>
		<link>http://www.stevesouders.com/blog/2009/12/01/google-analytics-goes-async/</link>
		<comments>http://www.stevesouders.com/blog/2009/12/01/google-analytics-goes-async/#comments</comments>
		<pubDate>Wed, 02 Dec 2009 00:36:09 +0000</pubDate>
		<dc:creator>Steve Souders</dc:creator>
				<category><![CDATA[EFWS]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[asynchronous]]></category>
		<category><![CDATA[ga]]></category>
		<category><![CDATA[google analytics]]></category>

		<guid isPermaLink="false">http://www.stevesouders.com/blog/?p=764</guid>
		<description><![CDATA[Today&#8217;s announcement that Google Analytics Launches Asynchronous Tracking is music to my ears. Not only does it make web sites faster, switching over to this async pattern improves uptime and increases the amount of analytics data gathered. I&#8217;ll touch on each of these three benefits, and wrap-up with an overview of the new code snippet. [...]]]></description>
			<content:encoded><![CDATA[<p>Today&#8217;s announcement that <a href="http://googlecode.blogspot.com/2009/12/google-analytics-launches-asynchronous.html">Google Analytics Launches Asynchronous Tracking</a> is music to my ears. Not only does it make web sites faster, switching over to this async pattern improves uptime and increases the amount of analytics data gathered. I&#8217;ll touch on each of these three benefits, and wrap-up with an overview of the new code snippet.</p>
<div style="font-size:1.3em;"><strong>Faster</strong></div>
<p>The pain of loading JavaScript files is that they block the page from rendering and block other resources from downloading. There are workarounds to these problems. Chapter 4 of <a href="http://www.amazon.com/Even-Faster-Web-Sites-Performance/dp/0596522304">Even Faster Web Sites</a> describes six techniques for <a href="http://www.stevesouders.com/blog/2009/04/27/loading-scripts-without-blocking/">Loading Scripts Without Blocking</a>. One of those, the Script DOM Element approach, is the technique used in the new Google Analytics async pattern. Google Analytics&#8217; ga.js file is a perfect example of a script that should be loaded asynchronously &#8211; it doesn&#8217;t add any content to the page, so we want to load it without blocking the images and stylesheets that give users what they really came to see.</p>
<div style="font-size:1.3em;"><strong>Improved Uptime</strong></div>
<p>What happens if a script takes a long time to load, or fails to load? Because scripts block rendering, users are left staring at an empty page. Google Analytics has an amazing infrastructure behind it, but any resource, especially from third parties, should be added cautiously. It&#8217;s great that the GA team is evangelizing a pattern that allows the web site to render while ga.js is being downloaded.</p>
<div style="font-size:1.3em;"><strong>More Data</strong></div>
<p>One workaround to the blocking problem is to move scripts to the bottom of the page. In fact, this is exactly what&#8217;s suggested in <a href="http://code.google.com/apis/analytics/docs/tracking/gaTrackingOverview.html#standardSetup">the old ga.js snippet</a>. But this means users who leave a page quickly won&#8217;t generate any analytics data (they leave before the script at the bottom finishes loading). Moving to the async pattern and loading it at the bottom of the page&#8217;s head, as suggested, means more of these quick page views get measured. This is too good to believe &#8211; not only do you get a faster, more resilient page, but you actually get better insights into your traffic.</p>
<div style="font-size:1.3em;"><strong>The Async Snippet</strong></div>
<p>Just to be clear, ga.js will continue to work even if web site owners don&#8217;t make any changes. But, if you want a faster site, greater uptime, and more data, here&#8217;s what the new async snippet looks like:</p>
<pre style="margin: 8px 0pt 16px 20px; padding: 8px; background: #F0F0F0;">var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-XXXXX-X']);
_gaq.push(['_trackPageview']);

(function() {
var ga = document.createElement('script');
ga.src = ('https:' == document.location.protocol ?
    'https://ssl' : 'http://www') +
    '.google-analytics.com/ga.js';
ga.setAttribute('async', 'true');
document.documentElement.firstChild.appendChild(ga);
})();</pre>
<p>It&#8217;s extremely cool to see this pattern being evangelized for such a major piece of the Internet. A few items of note:</p>
<ul>
<li>Obviously, you have to replace &#8220;UA-XXXXX-X&#8221; with your ID.</li>
<li>Since ga.js is being loaded asynchronously, there has to be a way for web site owners to couple their desired GA functions with the code when it finishes loading. This is done by pushing commands onto the Google Analytics queue object, _gaq.</li>
<li>Once all your callback commands are queued up, the ga.js script gets loaded. This is wrapped inside an anonymous function to avoid any namespace conflicts.</li>
<li>Inside the anonymous function is where we see the Script DOM Element approach being used &#8211; with two nice improvements. A &#8216;script&#8217; element is created and its SRC is set to the appropriate ga.js URL. Looking ahead to support of <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.html#attr-script-async">asynchronous scripts in HTML5</a>, the &#8216;async&#8217; attribute is set to &#8216;true&#8217;. Very nice! The main benefit of this is it tells the browser that subsequent scripts can be executed immediately &#8211; they don&#8217;t have to wait for ga.js. The last line adds the script element to the DOM. This is what triggers the actual download of ga.js. In most of my code I do document.getElementsByTagName(&#8220;head&#8221;)[0].appendChild, but that fails if the document doesn&#8217;t have a head element. This is a more robust implementation.</li>
</ul>
<p>It&#8217;s always hard to find the right spot on the complexibility curve. This async snippet hits it just right. It&#8217;s slightly more complex than <a href="http://code.google.com/apis/analytics/docs/tracking/gaTrackingOverview.html#standardSetup">the old pattern</a>, but not by much. Besides the benefits highlighted here, this new pattern is able to support more advanced usage patterns, including <a href="http://code.google.com/apis/analytics/docs/tracking/asyncUsageGuide.html#MultipleCommands">pushing an array of commands</a> and <a href="http://code.google.com/apis/analytics/docs/tracking/asyncUsageGuide.html#PushingFunctions">pushing functions</a>.</p>
<p>The theme driving much of my work this year is <em>fast by default</em>. I want high performance to be baked into the major components of the Web, so things are just fast. Seeing Google Analytics adopt this high performance async pattern is a huge win. But <a href="http://en.wikipedia.org/wiki/Pudding#Cultural_references">the proof is in the pudding</a>. If you switch over to the new async pattern, measure how it affects your page load times and the amount of data gathered, and add a comment below. My prediction: 200ms faster and 10% more data. What do you see?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.stevesouders.com/blog/2009/12/01/google-analytics-goes-async/feed/</wfw:commentRss>
		<slash:comments>55</slash:comments>
		</item>
		<item>
		<title>Yahoo! Search &#8211; new features, faster performance</title>
		<link>http://www.stevesouders.com/blog/2009/09/28/yahoo-search-new-features-faster-performance/</link>
		<comments>http://www.stevesouders.com/blog/2009/09/28/yahoo-search-new-features-faster-performance/#comments</comments>
		<pubDate>Tue, 29 Sep 2009 04:24:06 +0000</pubDate>
		<dc:creator>Steve Souders</dc:creator>
				<category><![CDATA[EFWS]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[data: uri]]></category>
		<category><![CDATA[Even Faster Web Sites]]></category>
		<category><![CDATA[lazy loading]]></category>
		<category><![CDATA[splitting the initial payload]]></category>
		<category><![CDATA[yahoo search]]></category>
		<category><![CDATA[YSlow]]></category>

		<guid isPermaLink="false">http://www.stevesouders.com/blog/?p=594</guid>
		<description><![CDATA[My last blog post was about Mobile Gmail performance best practices. It&#8217;s nice to follow that up with a review of a recent YDN blog post: Not Just a Pretty Face: Performance and the New Yahoo! Search. It&#8217;s great to see these industry leaders sharing their performance tips with the developer community and showing the [...]]]></description>
			<content:encoded><![CDATA[<p>My last blog post was about <a href="http://www.stevesouders.com/blog/2009/09/26/mobile-gmail-and-async-script-loading/">Mobile Gmail performance best practices</a>. It&#8217;s nice to follow that up with a review of a recent <a href="http://developer.yahoo.net/">YDN</a> blog post: <a href="http://developer.yahoo.net/blog/archives/2009/09/search_performance.html">Not Just a Pretty Face: Performance and the New Yahoo! Search</a>. It&#8217;s great to see these industry leaders sharing their performance tips with the developer community and showing the high value they put on making web pages faster.</p>
<p><a href="http://search.yahoo.com/">Yahoo! Search</a> recently added several <a href="http://www.ysearchblog.com/2009/09/22/welcome-to-the-new-yahoo-search/">rich new features</a>. Along with that came many performance improvements, resulting in a launch that not only had more features but was <em>faster</em> than the old version. What?! More features <em>and</em> faster performance?! Yes, you can have your cake and eat it, too. Here are some of the performance optimizations you can find in the new Yahoo! Search:</p>
<h2>data: URIs</h2>
<div style='margin-left: 40px;'>
<p>
Any HTML attribute that accepts a URL can also accept a <em>data: URI</em> &#8211; an encoded version of the actual HTTP response. This is a best practice for <a href="http://developer.yahoo.net/blog/archives/2007/04/rule_1_make_few.html">reducing the number of HTTP requests</a>. Yahoo! Search converted several of their CSS background images into data: URIs. For example, the gold Search button&#8217;s background looks like this:
</p>
<div style="margin: 4px 40px;">
<input style="padding: 0pt 23px; border: 1px solid #E5A716; background: #FDCE3E url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAZCAIAAAB/8tMoAAAAPUlEQVR42jWLQQqAQBDDOv3/9xSf4WlP7sQi4yGEFGr6tNZl0WFbCjxWh5i4mG127mN6/78P8q00HVeaGF4G+jQ9YP3upQAAAABJRU5ErkJggg==) repeat-x; padding: 0 23px; height: 26px; color: transparent" type="button" value="Search" /></div>
<p>If you look at their <a href="http://a.l.yimg.com/a/lib/s5/srp_metro_200909201526.css">stylesheet</a>, you&#8217;ll see that the background image uses a data: URI rather than an image URL:</p>
<div style="margin: 4px 0 4px 20px;"><code>.sbb {background-image: url('<strong>data:image/png;base64,iVBORw0KGgoAAAANSU...rkJggg==</strong>');}</code></div>
<p>
Using data: URIs instead of separate images eliminates HTTP requests. Even better, because the data: URI is in an external stylesheet (as opposed to the HTML document itself), it can be cached.
</p>
</div>
<h2>page flushing</h2>
<div style='margin-left: 40px;'>
<p>
<a href="http://www.stevesouders.com/blog/2009/05/18/flushing-the-document-early/">Flushing the document early</a> is a best practice I evangelize in <a href="http://www.amazon.com/Even-Faster-Web-Sites-Performance/dp/0596522304">Even Faster Web Sites</a>. Sending the HTML header and top navbar as quickly as possible allows the browser to start rendering the page more quickly. This visual feedback gives the user an experience that feels faster. If there are any resources in the head, the browser can get a jump on downloading them while the rest of page is still being stitched together. Yahoo! Search! sends down an initial chunk that includes the page header and search box. This HTML is fairly static, so the backend server can generate it quickly, before starting on the actual search results.
</p>
<p>Yahoo! Search goes even farther. The next chunk contains the remaining visible page content, but no JavaScript. The JavaScript is downloaded last, progressively enhancing the functionality of the page. This is a pattern I&#8217;m seeing more and more, especially in JavaScript-intensive web apps.
</p></div>
<h2>lazy loading</h2>
<div style='margin-left: 40px;'>
<p>
Yahoo! Search divided the JavaScript and CSS in the search results page into two categories: the bare minimum required to render the basic page and additional (heavy) functionality such as Search Assist and Search Pad. This is similar to another of my performance best practices: <a href="http://www.stevesouders.com/blog/2008/05/14/split-the-initial-payload/">Splitting the Initial Payload</a>. My advice focuses on JavaScript, but Yahoo! Search has extended the optimization to include CSS.
</p>
<p>My <a href="http://www.stevesouders.com/blog/2009/09/26/mobile-gmail-and-async-script-loading/">post on Mobile GMail</a> talked about their approach to lazy-loading JavaScript that avoids locking up the browser. Yahoo! Search uses the Script DOM Element approach &#8211; create a script element, set its src, and append it to the head element. This is a great approach for loading scripts in parallel. Yahoo! Search lazy-loads three scripts, so parallel loading is important. This technique does cause the JavaScript to be parsed and executed immediately. This isn&#8217;t an issue if it&#8217;s a small amount of code or the functionality is needed immediately. Otherwise, downloading the JavaScript and delaying the parsing and execution might lead to an even faster user experience.
</div>
<p>Kudos to the Yahoo! Search team. Great work, and thanks for sharing!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.stevesouders.com/blog/2009/09/28/yahoo-search-new-features-faster-performance/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Mobile Gmail and async script loading</title>
		<link>http://www.stevesouders.com/blog/2009/09/26/mobile-gmail-and-async-script-loading/</link>
		<comments>http://www.stevesouders.com/blog/2009/09/26/mobile-gmail-and-async-script-loading/#comments</comments>
		<pubDate>Sun, 27 Sep 2009 01:17:25 +0000</pubDate>
		<dc:creator>Steve Souders</dc:creator>
				<category><![CDATA[EFWS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[asynchronous]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[parallel]]></category>
		<category><![CDATA[Velocity]]></category>

		<guid isPermaLink="false">http://www.stevesouders.com/blog/?p=585</guid>
		<description><![CDATA[Mobile is the current web frontier where we&#8217;ll see the greatest growth in users and companies over the next few years. In case you didn&#8217;t see the announcement, Dion Almaer and Ben Galbraith just joined Palm to head up their developer relations program. At this week&#8217;s Velocity kick-off meeting, mobile performance was highlighted as a [...]]]></description>
			<content:encoded><![CDATA[<p>Mobile is the current web frontier where we&#8217;ll see the greatest growth in users and companies over the next few years.  In case you didn&#8217;t see <a href="http://pdnblog.palm.com/2009/09/ben-galbraith-and-dion-almaer-to-lead-developer-relations-team-at-palm/">the announcement</a>, <a href="http://almaer.com/blog/joining-palm-with-ben">Dion Almaer</a> and <a href="http://benzilla.galbraiths.org/2009/09/25/palm/">Ben Galbraith</a> just joined Palm to head up their developer relations program. At this week&#8217;s <a href="http://conferences.oreilly.com/velocity">Velocity</a> kick-off meeting, mobile performance was highlighted as a primary focus for next year&#8217;s conference.</p>
<p>With mobile on my mind, I was blown away by the awesome performance tips in this blog post: <a href="http://googlecode.blogspot.com/2009/09/gmail-for-mobile-html5-series-reducing.html">Gmail for Mobile HTML5 Series: Reducing Startup Latency</a>. This post hits on the main point of <a href="http://www.amazon.com/Even-Faster-Web-Sites-Performance/dp/0596522304">my recent book</a> &#8211; the impact of loading JavaScript. This is the #1 performance issue for today&#8217;s web apps. The problem is even worse for mobile devices where download times can be significantly worse than on the desktop.</p>
<p>One of the best practices I evangelize is <a href="http://www.stevesouders.com/blog/2008/05/14/split-the-initial-payload/"><em>splitting the initial payload</em></a>. The Google Mobile team echoes this advice, recommending that fast mobile web apps must separate their code into modules that are critical to page startup versus modules that can be lazy-loaded. It&#8217;s important to carefully consider when to lazy-load this additional JavaScript.</p>
<blockquote><p>One strategy is to lazy load the modules in the background once the home page has been loaded. This approach has some drawbacks. First, JavaScript execution in the browser is single threaded. So while you are loading the modules in the background, the rest of your app becomes non-responsive to user actions while the modules load. Second, it&#8217;s very difficult to decide when, and in what order, to load the modules. What if a user tries to access a feature/page you have yet to lazy load in the background? A better strategy is to associate the loading of a module with a user&#8217;s action.</p></blockquote>
<p>Loading JavaScript in the background does indeed freeze the UI and lockout the user. Even worse, they don&#8217;t know why this is happening. They didn&#8217;t invoke any action &#8211; the lazy-load was kicked off in the background. But, I&#8217;ve seen web apps adopt this recommendation of loading modules when the user requests the additional functionality, and that&#8217;s not pretty either. Waiting for a script to download, especially over mobile connections, injects too much of a delay. But the Google Mobile team found an ingenious workaround:</p>
<blockquote><p>&#8230;we wrote each module into a separate script tag and hid the code inside a comment block (/* */). When the resource first loads, none of the code is parsed since it is commented out. To load a module, find the DOM element for the corresponding script tag, strip out the comment block, and eval() the code.</p></blockquote>
<p>Your parents were wrong &#8211; you <em>can</em> have your cake and eat it, too! Commenting out the JavaScript code avoids locking up the browser, so the actual download can happen in the background without affecting the user experience. Once the code arrives, modules are eval&#8217;ed on an as-needed basis, without the delay of actually downloading the script. The eval does take time, but this is minimal  and is tied to the user&#8217;s actions, so it makes sense from the user&#8217;s perspective.</p>
<p>I&#8217;ve been working on <a href="http://www.stevesouders.com/blog/2009/04/27/loading-scripts-without-blocking/">ways to download scripts asynchronously</a> for two years. I&#8217;ve never seen this technique before. It&#8217;s very promising, and I hope to explore a few enhancements. It sounds like Google Mobile did the download as an HTML document in an iframe (&#8220;each module in a separate script tag&#8221;). This means it would have to be downloaded from the same domain as the main page &#8211; something common at Google but less typical on other web sites using CDNs or <a href="http://code.google.com/apis/ajaxlibs/">Google AJAX Libraries API</a>, or <a href="http://www.stevesouders.com/blog/2009/05/12/sharding-dominant-domains/">sharding resources across multiple domains</a>. It would be nice if each module could be a standalone script with the code commented out. This would avoid the same domain restrictions, and be faster since the scripts could be downloaded in parallel.</p>
<p>Hats off to the Google Mobile team. And thanks for sharing!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.stevesouders.com/blog/2009/09/26/mobile-gmail-and-async-script-loading/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Even Faster Web Sites in Skiathos</title>
		<link>http://www.stevesouders.com/blog/2009/09/09/even-faster-web-sites-in-skiathos/</link>
		<comments>http://www.stevesouders.com/blog/2009/09/09/even-faster-web-sites-in-skiathos/#comments</comments>
		<pubDate>Thu, 10 Sep 2009 06:10:32 +0000</pubDate>
		<dc:creator>Steve Souders</dc:creator>
				<category><![CDATA[Books]]></category>
		<category><![CDATA[EFWS]]></category>
		<category><![CDATA[HPWS]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Eleftherotypia]]></category>
		<category><![CDATA[Even Faster Web Sites]]></category>
		<category><![CDATA[skiathos]]></category>

		<guid isPermaLink="false">http://www.stevesouders.com/blog/?p=508</guid>
		<description><![CDATA[Ioannis Cherouvim, a software engineer from Greece, sent me this photo: He took Even Faster Web Sites with him on his vacation to Skiathos, a Greek island in the Aegean Sea. In his email, Ioannis mentioned that applying the tips from my previous book to the newspaper web site Eleftherotypia (&#8220;free press&#8221; in Greek) saved [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.cherouvim.com/mod_expires-and-cache-killers/">Ioannis Cherouvim</a>, a software engineer from Greece, sent me this photo:</p>
<p><img class="alignnone" title="EFWS in Skiathos" src="http://stevesouders.com/images/efws-in-skiathos-500x375.jpg" alt="" width="500" height="375" /></p>
<p>He took <a href="http://www.amazon.com/Even-Faster-Web-Sites-Performance/dp/0596522304">Even Faster Web Sites</a> with him on his vacation to <a href="http://en.wikipedia.org/wiki/Skiathos">Skiathos</a>, a Greek island in the Aegean Sea. In his email, Ioannis mentioned that applying the tips from my <a href="http://www.amazon.com/High-Performance-Web-Sites-Essential/dp/0596529309">previous book</a> to the newspaper web site <a href="http://www.enet.gr/">Eleftherotypia</a> (&#8220;free press&#8221; in Greek) saved &#8220;10GB traffic per day which really made a difference in our datacenter bill.&#8221; In addition, the users of the site got a better user experience.</p>
<p>Improved web performance and views of the Aegean Sea from the shores of a Greek island &#8211; now that&#8217;s heaven. Thanks, Ioannis &#8211; you made my day!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.stevesouders.com/blog/2009/09/09/even-faster-web-sites-in-skiathos/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Doloto: JavaScript download optimizer</title>
		<link>http://www.stevesouders.com/blog/2009/09/08/doloto-javascript-download-optimizer/</link>
		<comments>http://www.stevesouders.com/blog/2009/09/08/doloto-javascript-download-optimizer/#comments</comments>
		<pubDate>Wed, 09 Sep 2009 06:02:21 +0000</pubDate>
		<dc:creator>Steve Souders</dc:creator>
				<category><![CDATA[EFWS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Doloto]]></category>
		<category><![CDATA[microsoft]]></category>

		<guid isPermaLink="false">http://www.stevesouders.com/blog/?p=495</guid>
		<description><![CDATA[One of the speakers at Velocity 2008 was Ben Livshits from Microsoft Research. He spoke about Doloto, a system for splitting up huge JavaScript payloads for better performance. I talk about Doloto in Even Faster Web Sites. When I wrote the book, Doloto was an internal project, but that all changed last week when Microsoft [...]]]></description>
			<content:encoded><![CDATA[<p>One of the speakers at <a href="http://en.oreilly.com/velocity2008/public/content/home">Velocity 2008</a> was Ben Livshits from Microsoft Research. He spoke about <a href="http://msdn.microsoft.com/en-us/devlabs/ee423534.aspx">Doloto</a>, a system for splitting up huge JavaScript payloads for better performance. I talk about Doloto in <a href="http://www.amazon.com/Even-Faster-Web-Sites-Performance/dp/0596522304">Even Faster Web Sites</a>. When I wrote the book, Doloto was an internal project, but that all changed last week when Microsoft Research <a href="http://blogs.msdn.com/somasegar/archive/2009/09/04/doloto-on-devlabs.aspx">released Doloto to the public</a>.</p>
<p>The <a href="http://msdn.microsoft.com/en-us/devlabs/ee423534.aspx">project web site</a> describes Doloto as:</p>
<blockquote><p>&#8230;an AJAX application optimization tool, especially useful for large and complex Web 2.0 applications that contain a lot of code, such as Bing Maps, Hotmail, etc. Doloto analyzes AJAX application workloads and automatically performs code splitting of existing large Web 2.0 applications. After being processed by Doloto, an application will initially transfer only the portion of code necessary for application initialization.</p></blockquote>
<p>Anyone who has tried to do code analysis on JavaScript (a la <a href="http://code.google.com/p/google-caja/">Caja</a>) knows this is a complex problem. But it&#8217;s worth the effort:</p>
<blockquote><p>In our experiments across a number of AJAX applications and network conditions, Doloto reduced the amount of initial downloaded JavaScript code by over 40%, or hundreds of kilobytes resulting in startup often faster by 30-40%, depending on network conditions.</p></blockquote>
<p><a href="http://blogs.msdn.com/somasegar/archive/2009/09/04/doloto-on-devlabs.aspx"><img class="alignnone" title="Initial code download size savings with Doloto" src="http://0ebv5a.blu.livefilestore.com/y1pyfu4Y_3Vl3XBxTTxps7T06PXwA6Cd0m3oe_TXJ27moaAkAFAQUJoQ9W9iTYBFzM03MDeoAR-hfMzVwWt1wcfLg" alt="" width="546" height="344" /></a></p>
<p>Hats off to Ben and the rest of the Doloto team at Microsoft Research on the release of Doloto. This and other tools are sorely needed to help with some of the heavy lifting that now sits solely on the shoulders of web developers.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.stevesouders.com/blog/2009/09/08/doloto-javascript-download-optimizer/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>back in the saddle: EFWS! Velocity!</title>
		<link>http://www.stevesouders.com/blog/2009/07/20/back-in-the-saddle-efws-velocity/</link>
		<comments>http://www.stevesouders.com/blog/2009/07/20/back-in-the-saddle-efws-velocity/#comments</comments>
		<pubDate>Mon, 20 Jul 2009 19:32:36 +0000</pubDate>
		<dc:creator>Steve Souders</dc:creator>
				<category><![CDATA[Books]]></category>
		<category><![CDATA[Conferences]]></category>
		<category><![CDATA[EFWS]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[Velocity]]></category>
		<category><![CDATA[Even Faster Web Sites]]></category>
		<category><![CDATA[OSCON]]></category>

		<guid isPermaLink="false">http://www.stevesouders.com/blog/?p=456</guid>
		<description><![CDATA[The last few months are a blur for me. I get through stages of life like this and look back and wonder how I ever made it through alive (and why I ever set myself up for such stress). The big activities that dominated my time were Even Faster Web Sites and Velocity. Even Faster [...]]]></description>
			<content:encoded><![CDATA[<p>The last few months are a blur for me. I get through stages of life like this and look back and wonder how I ever made it through alive (and why I ever set myself up for such stress). The big activities that dominated my time were Even Faster Web Sites and Velocity.</p>
<h3>Even Faster Web Sites</h3>
<div style="float:right; margin: 0 8px 0 8px;"><a href="http://www.amazon.com/dp/0596522304?tag=stevsoud-20&amp;camp=213381&amp;creative=390973&amp;linkCode=as4&amp;creativeASIN=0596522304&amp;adid=1D3BSM7ENTSD0MDZF4E4&amp;"><img title="Even Faster Web Sites" src="http://stevesouders.com/images/efws-cover-84x110.gif" border="0" alt="" width="84" height="110" /></a></div>
<p><a href="http://www.amazon.com/dp/0596522304?tag=stevsoud-20&amp;camp=213381&amp;creative=390973&amp;linkCode=as4&amp;creativeASIN=0596522304&amp;adid=01WYHMGDH90A72SYN2M5&amp;">Even Faster Web Sites</a> is my second book of web performance best practices. This is a follow-on to my first book, <a href="http://www.amazon.com/dp/0596529309?tag=stevsoud-20&amp;camp=14573&amp;creative=327641&amp;linkCode=as1&amp;creativeASIN=0596529309&amp;adid=1V4ZRY9Z5BVXW853SHE2&amp;">High Performance Web Sites</a>. EFWS isn&#8217;t a second edition, it&#8217;s more like &#8220;Volume 2&#8243;. Both books contain 14 chapters, each chapter devoted to a separate performance topic. The best practices described in EFWS are completely new:</p>
<table border="0" cellspacing="0" cellpadding="2">
<tbody>
<tr>
<td>
<ol style="margin: 0">
<li>Understanding Ajax Performance</li>
<li>Creating Responsive Web Applications</li>
<li>Splitting the Initial Payload</li>
<li>Loading Scripts Without Blocking</li>
<li>Coupling Asynchronous Scripts</li>
<li>Positioning Inline Scripts</li>
<li>Writing Efficient JavaScript</li>
</ol>
</td>
<td>
<ol style="margin: 0" start="8">
<li>Scaling with Comet</li>
<li>Going Beyond Gzipping</li>
<li>Optimizing Images</li>
<li>Sharding Dominant Domains</li>
<li>Flushing the Document Early</li>
<li>Using Iframes Sparingly</li>
<li>Simplifying CSS Selectors</li>
</ol>
</td>
</tr>
</tbody>
</table>
<p>An exciting addition to EFWS is that six of the chapters were contributed by guest authors: Doug Crockford (Chap 1), Ben Galbraith and Dion Almaer (Chap 2), Nicholas Zakas (Chap 7), Dylan Schiemann (Chap 8), Tony Gentilcore (Chap 9), and Stoyan Stefanov and Nicole Sullivan (Chap 10). Web developers working on today&#8217;s content rich, dynamic web sites will benefit from the advice contained in Even Faster Web Sites.</p>
<h3>Velocity</h3>
<p><a href="http://en.oreilly.com/velocity2009">Velocity</a> is the web performance and operations conference that I co-chair with <a href="http://radar.oreilly.com/jesse/">Jesse Robbins</a>. Jesse, former &#8220;Master of Disaster&#8221; at Amazon and current CEO of <a href="http://www.opscode.com/">Opscode</a>, runs the operations track. I ride herd on the performance side of the conference. This was the second year for Velocity. The first year was a home run, drawing 600 attendees (far more than expected &#8211; we only made 400 swag bags) and containing a ton of great talks. Velocity 2009 (held in San Jose June 22-24) was an even bigger success: more attendees (700), more sponsors, more talks, and an additional day for workshops.</p>
<p>The bright spot for me at Velocity was the fact that so many speakers offered up stats on how performance is critical to a company&#8217;s business. I wrote a blog post on O&#8217;Reilly Radar about this: <a href="http://radar.oreilly.com/2009/07/velocity-making-your-site-fast.html">Velocity and the Bottom Line</a>. Here are some of the excerpted stats:</p>
<ul>
<li><a href="http://www.bing.com/">Bing</a> found that a 2 second slowdown caused a 4.3% reduction in revenue/user</li>
<li><a href="http://www.google.com/">Google Search</a> found that a 400 millisecond delay resulted in 0.59% fewer searches/user</li>
<li><a href="http://www.aol.com/">AOL</a> revealed that users that experience the fastest page load times view 50% more pages/visit than users experiencing the slowest page load times</li>
<li><a href="http://www.shopzilla.com/">Shopzilla</a> undertook a massive performance redesign reducing page load times from ~7 seconds to ~2 seconds, with a corresponding 7-12% increase in revenue and 50% reduction in hardware costs</li>
</ul>
<p>I love optimizing web performance because it raises the quality of engineering, reduces inefficiencies, and is <a href="http://www.stevesouders.com/blog/2008/03/06/how-green-is-your-web-page/">better for the planet</a>. But to get widespread adoption we need to motivate the non-engineering parts of the organization. That&#8217;s why these case studies on web performance improving the user experience <em>as well as </em>the company&#8217;s bottom line are important. I applaud these companies for not only tracking these results, but being willing to share them publicly. You can get more details from the Velocity <a href="http://velocityconference.blip.tv/">videos</a> and <a href="http://en.oreilly.com/velocity2009/public/schedule/proceedings">slides</a>.</p>
<h3>Back in the Saddle</h3>
<p>Over the next six months, I&#8217;ll be focusing on open sourcing many of the tools I&#8217;ve soft launched, including <a href="http://stevesouders.com/ua/">UA Profiler</a>, <a href="http://cuzillion.com/">Cuzillion</a>, <a href="http://stevesouders.com/hammerhead/">Hammerhead</a>, and <a href="http://stevesouders.com/episodes/">Episodes</a>. These are already &#8220;open source&#8221; per se, but they&#8217;re not active projects, with a code repository, bug database, roadmap, and active contributors. I plan on fixing that and will discuss this more during <a href="http://en.oreilly.com/oscon2009/public/schedule/detail/8057">my presentation at OSCON this week</a>. If you&#8217;re going to OSCON, I hope you&#8217;ll attend my session. If not, I&#8217;ll also be signing books at 1pm and providing performance consulting (for free!) at the Google booth at 3:30pm, both on Wednesday, July 22.</p>
<p>As you can see, even though Velocity and EFWS are behind me, there&#8217;s still a ton of work left to do. We&#8217;ll never be &#8220;done&#8221; fixing web performance. It&#8217;s like cleaning out your closets &#8211; they always fill up again. As we make our pages faster, some new challenge arises (mobile, rich media ads, emerging markets with poor connectivity) that requires more investigation and new solutions. Some people might find this depressing or daunting. Me? I&#8217;m psyched! &#8216;Scuse me while I roll up my sleeves.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.stevesouders.com/blog/2009/07/20/back-in-the-saddle-efws-velocity/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Simplifying CSS Selectors</title>
		<link>http://www.stevesouders.com/blog/2009/06/18/simplifying-css-selectors/</link>
		<comments>http://www.stevesouders.com/blog/2009/06/18/simplifying-css-selectors/#comments</comments>
		<pubDate>Thu, 18 Jun 2009 20:55:20 +0000</pubDate>
		<dc:creator>Steve Souders</dc:creator>
				<category><![CDATA[browsers]]></category>
		<category><![CDATA[EFWS]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[reflow]]></category>

		<guid isPermaLink="false">http://www.stevesouders.com/blog/?p=427</guid>
		<description><![CDATA[This post is based on a chapter from Even Faster Web Sites, the follow-up to High Performance Web Sites. Posts in this series include: chapters and contributing authors, Splitting the Initial Payload, Loading Scripts Without Blocking, Coupling Asynchronous Scripts, Positioning Inline Scripts, Sharding Dominant Domains, Flushing the Document Early, Using Iframes Sparingly, and Simplifying CSS [...]]]></description>
			<content:encoded><![CDATA[<p><em>This post is based on a chapter from <a href="http://www.amazon.com/gp/product/0596522304?ie=UTF8&amp;tag=stevsoud-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0596522304"><span style="text-decoration: underline;">Even Faster Web Sites</span></a>, the follow-up to <a href="http://www.amazon.com/dp/0596529309?tag=stevsoud-20&amp;camp=14573&amp;creative=327641&amp;linkCode=as1&amp;creativeASIN=0596529309&amp;adid=1S1KP4EV129EN37422C0&amp;"><span style="text-decoration: underline;">High Performance Web Sites</span></a>. </em><em>Posts in this series include: <a href="http://www.stevesouders.com/blog/2009/04/23/even-faster-web-sites/">chapters and contributing authors</a>, <a href="http://www.stevesouders.com/blog/2008/05/14/split-the-initial-payload/">Splitting the Initial Payload</a>, <a href="http://www.stevesouders.com/blog/2009/04/27/loading-scripts-without-blocking/">Loading Scripts Without Blocking</a>, <a href="http://www.stevesouders.com/blog/2008/12/27/coupling-async-scripts/">Coupling Asynchronous Scripts</a>, <a href="http://www.stevesouders.com/blog/2009/05/06/positioning-inline-scripts/">Positioning Inline Scripts</a>, <a href="http://www.stevesouders.com/blog/2009/05/12/sharding-dominant-domains/">Sharding Dominant Domains</a>, <a href="http://www.stevesouders.com/blog/2009/05/18/flushing-the-document-early/">Flushing the Document Early</a>, <a href="http://www.stevesouders.com/blog/2009/06/03/using-iframes-sparingly">Using Iframes Sparingly</a>, and <a href="http://www.stevesouders.com/blog/2009/06/18/simplifying-css-selectors/">Simplifying CSS Selectors</a>.<br />
</em></p>
<p>&#8220;Simplifying CSS Selectors&#8221; is the last chapter in my <a href="http://www.amazon.com/gp/product/0596522304?ie=UTF8&amp;tag=stevsoud-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0596522304">next book</a>. My investigation into CSS selector performance is therefore fairly recent. A few months ago, I wrote a blog post about the <a href="http://www.stevesouders.com/blog/2009/03/10/performance-impact-of-css-selectors/">Performance Impact of CSS Selectors</a>. It talks about the different types of CSS selectors, which ones are hypothesized to be the most painful, and how the impact of selector matching might be overestimated. It concludes with this hypothesis:</p>
<blockquote><p>For most web sites, the possible performance gains from optimizing CSS selectors will be small, and are not worth the costs. There are some types of CSS rules and interactions with JavaScript that can make a page noticeably slower. This is where the focus should be.</p></blockquote>
<p>I received a lot of feedback about situations where CSS selectors <em>do</em> make web pages noticeably slower. Looking for a common theme across these slow CSS test cases led me to this revelation from David Hyatt&#8217;s article on <a href="https://developer.mozilla.org/en/Writing_Efficient_CSS">Writing Efficient CSS for use in the Mozilla UI</a>:</p>
<blockquote><p>The style system matches a rule by starting with the rightmost selector and moving to the left through the rule’s selectors. As long as your little subtree continues to check out, the style system will continue moving to the left until it either matches the rule or bails out because of a mismatch.</p></blockquote>
<p>This illuminates where our optimization efforts should be focused: on CSS selectors that have a rightmost selector that matches a large number of elements in the page. The experiments from my previous blog post contain some CSS selectors that look expensive, but when examined in this new light we realize really aren&#8217;t worth worrying about, for example, <code>DIV DIV DIV P A.class0007 {}</code>. This selector has five levels of descendent matching that must be performed. This sounds complex. But when we look at the rightmost selector, <code>A.class0007</code>, we realize that there&#8217;s only one element in the entire page that the browser has to match against.</p>
<p>The key to optimizing CSS selectors is to focus on the rightmost selector, also called the <em>key selector </em>(coincidence?). Here&#8217;s a much more expensive selector: <code>A.class0007 * {}</code>. Although this selector might look simpler, it&#8217;s more expensive for the browser to match. Because the browser moves right to left, it starts by checking all the elements that match the key selector, &#8220;<code>*</code>&#8220;. This means the browser must try to match this selector against all elements in the page. This chart shows the difference in load times for the <a href="http://stevesouders.com/efws/css-selectors/universal.php">test page using this universal selector</a> compared with the previous <a href="http://stevesouders.com/efws/css-selectors/descendant.php">descendant selector test page</a>.</p>
<div style="margin-left: 80px;"><img src="http://stevesouders.com/efws/images/1404-css-selectors-browser-delta-universal.gif" alt="Load time difference for universal selector" /></p>
<div><strong>Load time difference for universal selector</strong></div>
</div>
<p>It&#8217;s clear that CSS selectors with a key selector that matches many elements can noticeably slow down web pages. Other examples of CSS selectors where the key selector might create a lot of work for the browser include:</p>
<pre style="margin-left: 40px;">A.class0007 DIV {}
#id0007 &gt; A {}
.class0007 [href] {}
DIV:first-child {}</pre>
<p>Not all CSS selectors hurt performance, even those that might look expensive. The key is focusing on CSS selectors with a wide-matching key selector. This becomes even more important for Web 2.0 applications where the number of DOM elements, CSS rules, and page reflows are even higher.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.stevesouders.com/blog/2009/06/18/simplifying-css-selectors/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
		<item>
		<title>Using Iframes Sparingly</title>
		<link>http://www.stevesouders.com/blog/2009/06/03/using-iframes-sparingly/</link>
		<comments>http://www.stevesouders.com/blog/2009/06/03/using-iframes-sparingly/#comments</comments>
		<pubDate>Thu, 04 Jun 2009 06:42:25 +0000</pubDate>
		<dc:creator>Steve Souders</dc:creator>
				<category><![CDATA[Ads]]></category>
		<category><![CDATA[browsers]]></category>
		<category><![CDATA[EFWS]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[connections]]></category>
		<category><![CDATA[Even Faster Web Sites]]></category>
		<category><![CDATA[iframes]]></category>

		<guid isPermaLink="false">http://www.stevesouders.com/blog/?p=403</guid>
		<description><![CDATA[This post is based on a chapter from Even Faster Web Sites, the follow-up to High Performance Web Sites. Posts in this series include: chapters and contributing authors, Splitting the Initial Payload, Loading Scripts Without Blocking, Coupling Asynchronous Scripts, Positioning Inline Scripts, Sharding Dominant Domains, Flushing the Document Early, Using Iframes Sparingly, and Simplifying CSS [...]]]></description>
			<content:encoded><![CDATA[<p><em>This post is based on a chapter from <a href="http://www.amazon.com/gp/product/0596522304?ie=UTF8&amp;tag=stevsoud-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0596522304"><span style="text-decoration: underline;">Even Faster Web Sites</span></a>, the follow-up to <a href="http://www.amazon.com/dp/0596529309?tag=stevsoud-20&amp;camp=14573&amp;creative=327641&amp;linkCode=as1&amp;creativeASIN=0596529309&amp;adid=1S1KP4EV129EN37422C0&amp;"><span style="text-decoration: underline;">High Performance Web Sites</span></a>. </em><em>Posts in this series include: <a href="http://www.stevesouders.com/blog/2009/04/23/even-faster-web-sites/">chapters and contributing authors</a>, <a href="http://www.stevesouders.com/blog/2008/05/14/split-the-initial-payload/">Splitting the Initial Payload</a>, <a href="http://www.stevesouders.com/blog/2009/04/27/loading-scripts-without-blocking/">Loading Scripts Without Blocking</a>, <a href="http://www.stevesouders.com/blog/2008/12/27/coupling-async-scripts/">Coupling Asynchronous Scripts</a>, <a href="http://www.stevesouders.com/blog/2009/05/06/positioning-inline-scripts/">Positioning Inline Scripts</a>, <a href="http://www.stevesouders.com/blog/2009/05/12/sharding-dominant-domains/">Sharding Dominant Domains</a>, <a href="http://www.stevesouders.com/blog/2009/05/18/flushing-the-document-early/">Flushing the Document Early</a>, </em><em><a href="http://www.stevesouders.com/blog/2009/06/03/using-iframes-sparingly">Using Iframes Sparingly</a>, and <a href="http://www.stevesouders.com/blog/2009/06/18/simplifying-css-selectors/">Simplifying CSS Selectors</a>.</em><em> </em></p>
<div style="float: right; margin: 8px;"><img class="alignnone" title="Cost of Elements" src="http://stevesouders.com/efws/images/1301-iframes-cost-of-elements.gif" alt="" width="308" height="384" /></p>
<p style="margin-top: 0; margin-bottom: 8px; text-align: center">Time to create 100 elements</p>
</div>
<p><a href="http://www.w3.org/TR/html4/present/frames.html#edef-IFRAME">Iframes</a> provide an easy way to embed content from one web site into another. But they should be used cautiously. They are 1-2 orders of magnitude more expensive to create than any other type of DOM element, including scripts and styles. The time to create 100 elements of various types shows how expensive iframes are.</p>
<p>Pages that use iframes typically don&#8217;t have that many of them, so the DOM creation time isn&#8217;t a big concern. The bigger issues involve the onload event and the connection pool.</p>
<p><strong>Iframes Block Onload</strong></p>
<p>It&#8217;s important that the window&#8217;s onload event fire as soon as possible. This causes the browser&#8217;s busy indicators to stop, letting the user know that the page is done loading. When the onload event is delayed, it gives the user the perception that the page is slower.</p>
<p>The window&#8217;s onload event doesn&#8217;t fire until all its iframes, and all the resources in these iframes, have fully loaded. In Safari and Chrome, setting the iframe&#8217;s SRC dynamically via JavaScript avoids this blocking behavior.</p>
<p><strong>One Connection Pool</strong></p>
<p>Browsers open a small number of connections to any given web server. Older browsers, including Internet Explorer 6 &amp; 7 and Firefox 2, only open two connections per hostname. This number has increased in newer browsers. Safari 3+ and Opera 9+ open four connections per hostname, while Chrome 1+, IE 8, and Firefox 3 open six connections per hostname. You can see the complete table in my <a href="http://www.stevesouders.com/blog/2008/03/20/roundup-on-parallel-connections/">Roundup on Parallel Connections</a>.</p>
<p>One might hope that an iframe would have its own connection pool, but that&#8217;s not the case. In all major browsers, the connections are shared between the main page and its iframes. This means it&#8217;s possible for the resources in an iframe to use up the available connections and block resources in the main page from loading. If the contents of the iframe are as important, or more important, than the main page, this is fine. However, if the iframe&#8217;s contents are less critical to the page, as is often the case, it&#8217;s undesirable for the iframe to commandeer the open connections. One workaround is to set the iframe&#8217;s SRC dynamically after the higher priority resources are done downloading.</p>
<p>5 of the 10 top U.S. web sites use iframes. In most cases, they&#8217;re used for ads. This is unfortunate, but understandable given the simplicity of using iframes for inserting content from an ad service. In many situations, iframes are the logical solution. But keep in mind the performance impact they can have on your page. When possible, avoid iframes. When necessary, use them sparingly.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.stevesouders.com/blog/2009/06/03/using-iframes-sparingly/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Flushing the Document Early</title>
		<link>http://www.stevesouders.com/blog/2009/05/18/flushing-the-document-early/</link>
		<comments>http://www.stevesouders.com/blog/2009/05/18/flushing-the-document-early/#comments</comments>
		<pubDate>Tue, 19 May 2009 06:02:46 +0000</pubDate>
		<dc:creator>Steve Souders</dc:creator>
				<category><![CDATA[Books]]></category>
		<category><![CDATA[EFWS]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[chunked encoding]]></category>
		<category><![CDATA[Even Faster Web Sites]]></category>
		<category><![CDATA[flushing]]></category>
		<category><![CDATA[web performance]]></category>

		<guid isPermaLink="false">http://www.stevesouders.com/blog/?p=386</guid>
		<description><![CDATA[This post is based on a chapter from Even Faster Web Sites, the follow-up to High Performance Web Sites. Posts in this series include: chapters and contributing authors, Splitting the Initial Payload, Loading Scripts Without Blocking, Coupling Asynchronous Scripts, Positioning Inline Scripts, Sharding Dominant Domains, Flushing the Document Early, Using Iframes Sparingly, and Simplifying CSS [...]]]></description>
			<content:encoded><![CDATA[<p><em>This post is based on a chapter from <a href="http://www.amazon.com/gp/product/0596522304?ie=UTF8&amp;tag=stevsoud-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0596522304"><span style="text-decoration: underline;">Even Faster Web Sites</span></a>, the follow-up to <a href="http://www.amazon.com/dp/0596529309?tag=stevsoud-20&amp;camp=14573&amp;creative=327641&amp;linkCode=as1&amp;creativeASIN=0596529309&amp;adid=1S1KP4EV129EN37422C0&amp;"><span style="text-decoration: underline;">High Performance Web Sites</span></a>. </em><em>Posts in this series include: <a href="http://www.stevesouders.com/blog/2009/04/23/even-faster-web-sites/">chapters and contributing authors</a>, <a href="http://www.stevesouders.com/blog/2008/05/14/split-the-initial-payload/">Splitting the Initial Payload</a>, <a href="http://www.stevesouders.com/blog/2009/04/27/loading-scripts-without-blocking/">Loading Scripts Without Blocking</a>, <a href="http://www.stevesouders.com/blog/2008/12/27/coupling-async-scripts/">Coupling Asynchronous Scripts</a>, <a href="http://www.stevesouders.com/blog/2009/05/06/positioning-inline-scripts/">Positioning Inline Scripts</a>, <a href="http://www.stevesouders.com/blog/2009/05/12/sharding-dominant-domains/">Sharding Dominant Domains</a>, <a href="http://www.stevesouders.com/blog/2009/05/18/flushing-the-document-early/">Flushing the Document Early</a>, </em><em><a href="http://www.stevesouders.com/blog/2009/06/03/using-iframes-sparingly">Using Iframes Sparingly</a>, and <a href="http://www.stevesouders.com/blog/2009/06/18/simplifying-css-selectors/">Simplifying CSS Selectors</a>.</em></p>
<p><em> </em></p>
<p><em></em>The Performance Golden Rule reminds us that for most web sites, 80-90% of the load time is on the front end. However, for some pages, the time it takes the back end to generate the HTML document is more than 10-20% of the overall page load time. Even if the HTML document is generated quickly on the back end, it may still take a long time before it&#8217;s received by the browser for users in remote locations or with slow connections. While the HTML document is being generated on the back end and sent over the wire, the browser is waiting idly. What a waste! Instead of letting the browser sit there doing nothing, web developers can use flushing to jumpstart page loading even before the HTML document response is fully received.</p>
<p><em>Flushing</em> is when the server sends the initial part of the HTML document to the client before the entire response is ready. All major browsers start parsing the partial response. When done correctly, flushing results in a page that loads and feels faster. The key is choosing the right point at which to flush the partial HTML document response. The flush should occur <em>before</em> the expensive parts of the back end work, such as database queries and web service calls. But the flush should occur <em>after</em> the initial response has enough content to keep the browser busy. The part of the HTML document that is flushed should contain some resources as well as some visible content. If resources (e.g., stylesheets, external scripts, and images) are included, the browser gets an early start on its download work. If some visible content is included, the user receives feedback sooner that the page is loading.</p>
<p>Most HTML templating languages, including PHP, Perl, Python, and Ruby, contain a &#8220;flush&#8221; function. Getting flushing to work can be tricky. Problems arise when output is buffered, chunked encoding is disabled, proxies or anti-virus software interfere, or the flushed response is too small. Scanning the comments in <a href="http://www.php.net/flush">PHP&#8217;s flush documentation</a> shows that it can be hard to get all the details correct. Perhaps that&#8217;s why most of the U.S. top 10 sites don&#8217;t flush the document early. One that does is Google Search.</p>
<div style="margin-left: 40px;"><img title="Google Search flushing early" src="http://stevesouders.com/efws/images/1204-flush-google-search-waterfall.gif" border="1" alt="Google Search flushing early" width="353" height="82" /></p>
<p><strong>Google Search flushing early</strong></div>
<p>The HTTP waterfall chart for Google Search shows the benefits of flushing the document early. While the HTML document response (the first bar) is still being received, the browser has already started downloading one of the images used in the page, <a href="http://www.google.com/images/nav_logo4.png">nav_logo4.png</a> (the second bar). By flushing the document early, you make your pages start downloading resources and rendering content more quickly. This is a benefit that all users will appreciate, especially those with slow Internet connections and high latency.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.stevesouders.com/blog/2009/05/18/flushing-the-document-early/feed/</wfw:commentRss>
		<slash:comments>23</slash:comments>
		</item>
	</channel>
</rss>

