In his presentation at Breaking Development in San Diego CA Ilya Grigorik explained why mobile Web experiences can be slow and how to optimize your sites for quick rendering. Here's my notes from his talk on Optimizing the Critical Rendering Path: hard facts and implications.
- We care about mobile performance because people need fast experiences on the Web. There's lot of studies that highlight the importance of speed. More than half of people with a bad loading experience on mobile, won't come back.
- Speed is a feature. You can quantify its impact on the metrics you care about.
Network Latency
- The critical rendering path is a series of steps that need to take place in order to render a page in a browser.
- If you respond in 10ms, an experience feels instant. If it takes more than 1s, people may fall off.
- What happens with a 4G connection? First, the radio on your phone needs to talk to a tower. That can take 100s of milliseconds. Once a the network assigns a resource, then you can start transmitting data. From there it goes to a carrier's network and finally to a service's (external) network. On LTE this process takes 40-50ms. on Edge it can take 600ms-700ms.
- That's just one packet. Our web pages have multiple packets (the average is 50 resources).
- Before that then, we do a DNS lookup, a new TCP connection, and finally a HTTP request.
- Round trips matter. They are the biggest bottleneck to mobile performance.
- 3G networks will not be eclipsed by 4G networks around the World until 2020.
- The initial latency (for set-up) takes up to 600-3500ms on 3G and 300-600ms on 4G. These are network constraints responsible for one http request.
- Now a server connection is opened, you can't yet push data at full capacity. Instead TCP slow start sends a little bit of data, and scales up bandwidth capacity as the connection gets established.
- To fetch a 40KB on 4G takes 700ms. That's under great circumstances.
- You lose half of your 1s budget to network latency. There is no room for redirects on mobile. They add to this latency.
Browser Rendering
- As HTML bytes arrive, the DOM is constructed incrementally. You can flush part of the page from the server immediately.
- We can't process CSS incrementally like HMTL. We have to wait for the full CSS file in order to construct the page.
- The DOM plus the style information is intersected in a render tree, which is then painted on the screen. Once layout is complete, then pixels can be rendered on the CPU, transferred to GPU, and finally displayed.
- Stream your HTML response to the client. Don't wait to render the full HTML file. Flush early, flush often.
- Get CSS down to the client as soon as possible. It is a blocking asset.
- What about Javascript? In some ways Javascript is similar to CSS except it can modify the DOM and CSS.
- Eliminate blocking Javascript: Async all the scripts you can. They download in the background and execute when ready. If you are not modifying HTML, you should use async.
- We don't need to render the entire page in one second, we need to render the above the fold content. To accomplish this you need one roundtrip, a fast server, and no redirects.
Getting to One Second
- Use a base CSS file for your above the fold content and load the remaining styles sheets later.
- Inline your above the fold CSS into the page. Yes there's a trade-off here but it worth making now. Keep this and the CSS to 14KB max.
- Move your Javascript out of the header and defer them til later.
- Paint above the fold, then load the rest of your assets.
- There is no reason an analytics script should be blocking your page rendering.
- These optimizations apply equally well to the desktop world.
- Identifying critical CSS can be hard use an audit tool to determine what is needed.
- Google's Page Speed tool now has the option to inline the above the fold CSS you need to render your page.
- Optimize for visual progress instead of full page load times.
- Count the roundtrips. You should know exactly hoe many roundtrips your page requires to get the first (useful) render.