The last five years have seen a remarkable series of advances in use of JavaScript on the Web. JavaScript has gone from a language for adding interactivity to a key driver for innovation on the Web. A new generation of applications such as Gmail and Office Web Applications use thousands (or hundreds of thousands) of lines of JavaScript to deliver functionality and complexity similar to traditional desktop applications. With the advent of AJAX and script libraries, nearly every new site today makes use of JavaScript. These changes have also pushed browsers and script engines to evolve rapidly to keep up with user and developer needs to have fast, responsive applications and sites.
The IE9 Platform Preview includes the first release of our new JavaScript engine, codenamed Chakra, which fundamentally changes the performance characteristics of JavaScript inside Internet Explorer 9. Chakra includes a new JavaScript compiler that compiles JavaScript source code into high-quality native machine code, a new interpreter for executing script on traditional web pages, and improvements to the JavaScript runtime and libraries.
In this post, we look at the engine we’re building in IE9, and our approach to script performance.
A Look Back at IE8
IE8, like other versions of IE before it, included a script interpreter for running JavaScript. Pure interpreters are usually adequate for traditional web pages with limited amounts of script, and we did a lot of work to improve performance of these sites in Internet Explorer 8, both in script as well as across the browser.
With IE9, we decided that we needed a better approach to building a script engine for the present and future demands of the Web. Clearly, the new engine had to be able to run traditional pages well. But the engine also needed to perform well on Web applications of today and the HTML5 application of tomorrow, as well as keep up with changes in the Web and in the devices used to browse it.
Benchmark Graphs and Traditional JavaScript Performance
In any discussion of JavaScript engine performance, one dimension always comes up first: that of pure execution speed. How fast does an engine get you from point A to point B in a JavaScript program? A number of well-known benchmarks have tried to represent JavaScript execution speed in different ways.
The most famous of these, the WebKit’s SunSpider benchmark, tries to measure execution of pure JavaScript in the engine. WebKit’s SunSpider benchmark performs tasks like string manipulation and mathematical operations. These test not only the ability of the engine to execute user code fast, but performance of runtime libraries such as regular expressions and arrays. Other benchmarks such as Dromaeo measure a broader set of scenarios, like common JavaScript language patterns, such as closures, and interaction with the HTML DOM.
As browsers have made their interpreters faster and added various forms of code generation, their scores on these benchmarks have improved. Over time, the relative gap between browsers on these benchmarks has narrowed significantly. In the work we’ve done for the IE9 Platform Preview, we have already substantially improved performance from IE8, since PDC, and will continue to do so as we work on IE9.
Going Beyond the Benchmarks
But performance of JavaScript in the browser is about much more than benchmarks. Browsers today need to deliver great performance across a broad spectrum of the Web from individual pages to complex Web applications, and on a variety of platforms. To run the Web well, a browser’s script engine must enable:
An engine should be able to easily adapt to changes in applications and patterns used on the Web, and to changes in hardware used to view the Web.
- Great responsiveness in loading web pages with script. In our tests, we find that typical sites and applications use 10% to 30% of page load time running script. Code compilation and optimizations aren’t always effective, because the time needed to do this may offset the savings of running optimized code.
- Responsive modern Web applications. Script-intensive sites such as Gmail and some of the IE9 TestDrive demos behave more like applications than static web pages, and can spend much as 30% to 90% of time doing operations on script.
- An optimized experience on platforms from multi-core desktops to netbooks and mobile devices. User code in an HTML and JavaScript application is mostly single-threaded, but on today’s modern multi-core machines, browsers should find ways to use other cores intelligently to improve performance. At the same time, browsers must also run well on netbooks and low-power machines.
Qualities of the IE9 JavaScript Engine
So, let’s take a look at how we are building IE9 to meet these characteristics:
JavaScript Background Compilation: Many script engines today start with an optimized interpreter, and compile individual sections or methods into machine code to run faster. Others always compile JavaScript into machine code before running it, often compiling each method as it is needed. Both these approaches have to trade off quality or quantity of compiled code against execution speed. Generating high-quality code for today’s applications requires time to optimize the compiled code.
IE9 includes a fast interpreter for running pages quickly on startup. For compilation, we have a background code generator that compiles script code, and we push compiled methods back into the application. Because the code generator runs in the background, it can take advantage of today’s advanced multi-core machines and generate higher-quality code, while not blocking initial execution of the application.
Type Optimizations: One of the most important aspects of enabling performance on JavaScript is to create an efficient type system. The IE9 script engine uses many of the techniques common in modern dynamic language implementations, including type representation, polymorphic inline caching (also called type evolution or hidden classes), and efficient implementation of machine types.
Fast Interpreter: For pages where immediate execution in the interpreter is important, IE9 includes a new interpreter which uses a register-based layout, efficient opcode, and use of type optimizations.
Library Optimizations: The performance of JavaScript pages and applications depends heavily on key aspects of the script runtime library: strings, arrays, objects, and regular expressions. We are investing in these areas for IE9. These libraries require careful tuning for the real Web - one example is the execution of regular expressions. Most script engines today use compilation and optimization techniques to run regular expressions faster, and IE9 includes an improved regular expression implementation. In analyzing real world Web sites, we find a set of patterns used frequently, but we also find unique cases – for example, a site that creates hundreds of regular expressions and uses very few of them – we will continue to use this data to tune our regular expression implementation and other library features for IE9.
What Comes Next?
The steady rise of JavaScript performance in browsers leads to an obvious question: just how fast can JavaScript in the browser run? We know from measurements in the programming languages space that JavaScript is still limited in execution performance compared to C++ or statically typed languages. But code compilation, dynamic type inference and other innovations have enabled JavaScript to close that gap considerably.
As we work on IE9, we will continue to improve all facets of script performance: tuning our compiler, type system, libraries, and other runtime aspects such as memory management and DOM interoperability. We will also work on other dimensions of performance, such as memory usage and power consumption. The script engines of tomorrow will be judged how well they tune their performance across all these dimensions, across the entire Web.
We will also need the JavaScript language and runtime to evolve to meet the growing needs of developers and users. That’s why we are also working with other JavaScript engine implementers in the ECMA Script committeeto evolve JavaScript in a responsible way that maintains compatibility with today’s Web, and meets the needs of tomorrow’s HTML5 applications.
Shanku Niyogi
General Manager, JavaScript team
More...