June 22, 2016 10:00 am

JavaScript performance updates in Microsoft Edge and Chakra

By / Program Manager, Chakra

Since we first started work on the Chakra JavaScript engine, it has been our mission and priority to make JavaScript faster for the real-world web, and to continuously improve the experience of browsing in Microsoft Edge (and previously Internet Explorer). We’ve had a very busy year, with highlights like taking Chakra open-source, delivering ES2015 & beyond, experimenting with WebAssembly and more!

Through all of this, performance remains a principal theme – our team regularly looks at customer feedback and telemetry data to find potential patterns that slow down user experience, and tunes Chakra to provide substantial boosts to the web. Today, we’d like to share a few recent Chakra improvements coming up in the Windows 10 Anniversary Update, which you can preview today on recent Windows 10 Insider Preview builds.

Memory optimizations in functions

One of the code patterns on the web is the abundance of small-sized functions in scripts. This isn’t particularly a surprise as it is common developer practice to break down complex coding logic into many smaller pieces. The practice reduces repetitiveness and makes reading, debugging and testing the code much easier. Even better it can have a performance advantage, as smaller functions are generally easier to inline and the profiler can target the ‘hottest’ ones to produce JIT’ed code.

To optimize for this pattern especially in terms of memory consumption, Chakra has refactored the metadata format used for each function (internally referred to as FunctionBody). Based on data, pointers in FunctionBody that point to rarely-used information have been moved to a dynamic auxiliary structure and will not be instantiated and consume memory unless necessary. A good example is the asm.js-related data which is not applicable for most functions. Most of the 32-bit counters in FunctionBody were also observed to rarely have values over 256, such as the variable count or object literal count within a function. Thus these counters have been replaced by a compact structure that uses a single byte for each counter and those counters can be promoted to full 32-bit values if needed. Combined with a good number of functions, these seemingly subtle optimizations can make a big difference in reducing memory overhead (we’ll share our experiments later).

Diagram showing pointers and counters in FunctionBody moved to memory-saving structures

Many pointers and counters in FunctionBody have been moved to memory-saving structures

Deferred parsing for event-handlers

The modern web is a very interactive place, and inside almost every page there lies an event system with plenty of event-handlers defining the behavior of button-clicks, mouse-overs and many other events. However, unless the associated events are triggered, event-handlers are basically dead code. And in fact more often than not many of them end up unused during a browsing session. Just think about how many buttons or textboxes you left untouched the last time you visited your Facebook home page and imagine these controls and others all have event-handlers associated with them. Taking advantage of the formerly introduced deferred-parsing feature, Microsoft Edge and Chakra now delays the full parsing and bytecode generation of event-handlers until they are first called. Chakra uses a smaller representation for partially-parsed handlers, so the optimization not only improves the start-up time but also saves memory from any unused handlers.

The combination of deferred parsing for event-handlers and the memory optimizations in FunctionBody can together shrink a fair amount of memory footprint for each page. Though the actual savings depend highly on the pages being loaded and thus is quite hard to generalize, our experiment on a small sample of top-visited sites shows that these optimizations along with other smaller tweaks typically reduce about 4% to 10% of memory usage per page opened in Microsoft Edge, with cases where the savings reach over 20%.

Synthetic JavaScript benchmarks

All of our performance efforts are driven by data from the real world web and aim to enhance the actual end user experience. However, we are still frequently asked about JavaScript benchmark performance, and while it doesn’t always correspond directly to real-world performance, it can be useful at a high level and to illustrate improvement over time. Let’s look at where Microsoft Edge stands at the moment, as compared to other major browsers on two established JavaScript benchmarks maintained by Google and Apple respectively. The results below show Microsoft Edge continuing to lead both benchmarks.

Chart comparing browser performance on Google Octane and Apple Jetstream benchmarks.

All measures collected on 64-bit browsers running 64-bit Windows 10 Anniversary Update (1607)

We are very excited to share our performance effort to reduce memory footprint and start-up time with you. The road to better performance never ends, and we’re as committed as ever to making JavaScript faster. There will be more improvements in the summer months, so stay tuned for additional updates! Until then, we love feedback and rely on it to help us improve. You can always get in touch on Twitter via @MSEdgeDev and @ChakraCore, or the ChakraCore repo on GitHub.

Limin Zhu, Program Manager, Chakra Team

Updated February 22, 2017 2:23 pm