Web 2.0 Notes: Even Faster Websites
Workshop Title
Even Faster Websites
Presenter
Steve Souders (Google)
This was the third year in a row that Souders has presented his findings at Web 2.0. Here are my posts from year 1 and year 2. As usual, Souders has been hard at work running experiments on the performance of every part of the web browser, from initiating HTTP requests to rendering CSS. His central nugget of wisdom is that the vast majority of a user’s perceived wait time can be attributed to the frontend. This was an unconventional idea when he debuted it several years ago, but it’s common knowledge now and has only become more true over time. We frontend engineers are writing richer and richer browser-side code, nowadays.
However, my impression of this particular talk was that much of today’s research into frontend optimization is achieving diminishing returns. Instructables benefited greatly from Souders’ first talk, back in 2007, but the CSS optimizations introduced in this talk would shave very little off a user’s wait time. I was reminded, however, that I should install YSlow, which is an open-source plugin that will automatically identify performance bottlenecks on Instructables. I’m pretty sure there is plenty low-hanging fruit that we haven’t harvested, performance-wise.
Practicality aside, Souder’s talk was very interesting. The fact that CSS rules are parsed right-to-left was an eye-opener. I’m not going to go back and optimize all Instructables’ CSS, but this one nugget will allow me to avoid writing any egregiously slow selectors in the future.
You can find full notes and a link to the slides after the jump.
Where we Are Now
Review of Souders’ start with frontend optimization, starting a few years ago, when he realized that the majority (in many cases the vast majority) of the user’s wait time was due to processing after the HTML has been generated and downloaded. He estimates 80-90%, even with primed caches.
Flashes the 14 priorities rules that we’ve seen in earlier talks. Since then the following things have developed:
- This rule analysis was codified and automated with YSlow, an open-source Firebug plugin.
- The O’Reilly Velocity conference has been the forum for the developer community to develop new strategies and research in this field.
- Taught a class on this topic at Stanford recently.
- Published High Performance Web Sites
- About to publish Even Faster Websites (A number of other authors contributed to this book; see the slides for the list.)
- Splitting the initial payload
- Loading scripts without blocking
- Coupling asynchronous scripts
- Positioning inline scripts
- Sharding dominant domains
- Flushing the document early
- Using iframes sparingly
- Simplifying CSS Selectors
Best Practices
Souders reviews the last three. Most of these techniques are optimizations that are best pursued once the low-hanging fruit easily attached with YSlow have been taken.
- Flushing the document early
- Really important in exceptional cases when the server-side processing actually takes a long time (liek 30%-40% of the load time, e.g. Facebook.)
- Flush commands get any chars in stdout to be forced immediately to the browser.
- Calling a flush function in your server-side environment as soon as included request references (e.g. scripts and images) have been generated allows the browser to start downloading those resources while the rest of the HTML page is still being generated.
- Gotchas
- Some PHP-specific ones skipped, here.
- Transfer-Encoding: chunked (necessary header)
- gzip – Apache’s DeflateBufferSize before 2.2.8 (lower bound on response size disallows flushing below certain size)
- Proxies and Anti-virus software will sometimes trap the server response and won’t forward any data to the client until the whole page is complete.
- Safari and Chrome both have lower bounds as well. 1K and 2K respectively.
- Watch out for domain blocking. Move flushed resources to different subdomains, if necessary (e.g. domain sharding.)
- Simplifying CSS Selectors. See this post
- Review of ID selectors, class selectors, type selectors. These are fast
- Slow selectors are more advanced ones: Sibling, Child, Descendant, Universal, and Attribute Selectors. Pseudo classes and elements are also expensive.
- Issue: By necessity, browsers read selectors right-to-left. So, a Selector like
#toc > LI { font-weight: bold; }is going to look through all LIs for that id, instead of the intuitive thing where the id element is found first. - Rules
- avoid universal selectors
- don’t qualify ID selectrs
- don’t qualify class selectors
- make rules as specific as possible
- avoid descendant selectors
- avoid tag-child selectors
- rely on inheritance
- Several of these are an issue for maintainability. We use qualified selectors extensively at Instructables.
- Testing the selectors
- Studies have been done on this that show that certain browsers’ performance degrades much faster than others. All browsers do badly with complex selectors, but some have optimized simpler ones better than others.
- Souders extended these studies, since they were so exaggerated. He found that when testing more typical CSS conditions that the largest deltas were just 30ms.
- Remembering the RTL lookup rule really gets the performance gains, because truly horrible mistakes here can add up to hundreds of ms of delay. Here are examples of bad RTL selectors:
- Reflow time vs. Load Time
- Reflows are triggered by an inconsistent set of DOM manipulations, depending on browser. Opera does a great job, here. But FF and IE do bad jobs.
- Note: efficient CSS come at a cost: page weight
- focus optimization on selectors where the key selector (rightmost selector) matches many elements
- Avoiding @import
- Link followed by @import causes blocking in IE
- @import in another stylesheet causes blocking in all browsers
- many @imports followed by a script, IE reverses the order, causing blocking
- There are a lot of nuances. If you can, just avoid @import.
The bottom line on frontend optimization is that it’s a cost Savings: reduced hardware needed, reduced bandwidth.
Related Posts:
- Web 2.0 Notes: Optimizing the Frontend (April, 2008)
- Optimizing the Frontend (April, 2007)
- CSS Cleanup (April, 2008)
- It lives! (April, 2007)
- Web 2.0 Notes: Brian Dillard on Hacking the Browser (April, 2008)
