JavaScript Start-up Performance

Addy Osmani
Feb 9, 2017 · 12 min read
A simplified view of how V8 works. This is our idealized pipeline that we’re working towards.

What slows our web apps from booting up?

Parsing, Compiling and Executing scripts are things a JavaScript engine spends significant time in during start-up. This matters as if it takes a while, it can delay how soon users can interact with our site. Imagine if they can see a button but not click or touch it for multiple seconds. This can degrade the user experience.

Parse & Compile times for a popular website using V8’s Runtime Call Stats in Chrome Canary. Notice how a slow Parse/Compile on desktop can take far longer on average mobile phones.
The pink area (JavaScript) represents time spent in V8 and Blink’s C++, while the orange and yellow represent parse and compile.
Sam Saccone calls out the cost of JS parse in ‘Planning for Performance
Parse times for a 1MB bundle of JavaScript across desktop & mobile devices of differing classes. Notice how close a high-end phone like an iPhone 7 is to perf on a Macbook Pro vs the performance as we go down the graph towards average mobile hardware.

What Are JavaScript Parse & Compile bottlenecks for the average website?

“Buuuut, I’m not Facebook”, I hear you say dear, reader. “How heavy are Parse & Compile times for average sites out in the wild?”, you might be asking. Let’s science this out!

HTTPArchive stat: the average page ships down 420KB of JavaScript

Measuring JavaScript Parse & Compile today

Chrome DevTools

A custom Google Analytics dimension for ‘parse’ allows me to measure JavaScript parse times from real users and devices hitting my pages in the wild.

What can we do to lower our JavaScript parse times today?

  • Ship less JavaScript. The less script that requires parsing, the lower our overall time spent in the parse & compile phases will be.
  • Use code-splitting to only ship the code a user needs for a route and lazy load the rest. This probably is going to help the most to avoid parsing too much JS. Patterns like PRPL encourage this type of route-based chunking, now used by Flipkart, Housing.com and Twitter.
  • Script streaming: In the past, V8 have told developers to use `async/defer` to opt into script streaming for parse-time improvements of between 10–20%. This allows the HTML parser to at least detect the resource early, push the work to the script streaming thread and not halt the document parsing. Now that this is done for parser-blocking scripts too, I don’t think there’s anything actionable we need to do here. V8 recommend loading larger bundles earlier on as there’s only one streamer thread (more on this later)
  • Measure the parse cost of our dependencies, such as libraries and frameworks. Where possible, switch them out for dependencies with faster parse times (e.g switch React for Preact or Inferno, which require fewer bytes to bootup and have smaller parse/compile times). Paul Lewis covered framework bootup costs in a recent article. As Sebastian Markbage has also noted, a good way to measure start-up costs for frameworks is to first render a view, delete and then render again as this can tell you how it scales. The first render tends to warm up a bunch of lazily compiled code, which a larger tree can benefit from when it scales.
Nolan Lawson’s ‘Solving the Web Performance Crisis

What are browsers doing to improve Parse & Compile times today?

Developers are not the only ones to still be catching up on real-world start-up times being an area for improvement. V8 discovered that Octane, one of our more historical benchmarks, was a poor proxy for real-world performance on the 25 popular sites we usually test. Octane can be a poor proxy for 1) JavaScript frameworks (typically code that isn’t mono/polymorphic) and 2) real-page app startup (where most code is cold). These two use-cases are pretty important for the web. That said, Octane isn’t unreasonable for all kinds of workloads.

From using V8’s code caching
  • For scripts of Service Worker: Code caching triggers for scripts that are executed twice in 72 hours.
  • For scripts stored in Cache Storage via Service Worker: Code caching triggers for scripts in the first execution.

Conclusions

Start-up performance matters. A combination of slow parse, compile and execution times can be a real bottleneck for pages that wish to boot-up quickly. Measure how long your pages spend in this phase. Discover what you can do to make it faster.

Read More

reloading

Ideas for efficient loading on the web

Thanks to Malte Ubl.

Addy Osmani

Written by

Eng. Manager at Google working on Chrome • Passionate about making the web fast.

reloading

reloading

Ideas for efficient loading on the web