• JavaScript Engines: An Overview
  • By Mahdhi Rezvi
  • The Nuggets translation Project
  • Permanent link to this article: github.com/xitu/gold-m…
  • Translator: Isildur46
  • Proofreader: Chorer, CaptainWang98

JavaScript Engine Overview

The introduction

A JavaScript engine is a program or interpreter that executes JavaScript code. JavaScript engines can be implemented in many programming languages. For example, the V8 engine used by Chrome is written in C++, while the SpiderMonkey engine in Firefox is written in C and C++.

A JavaScript engine can be implemented as a standard interpreter or as a just-in-time compiler that compiles JavaScript into some form of bytecode. The first JavaScript engines were mostly interpreters, but most modern engines use just-in-time compilation (JIT) to improve performance.

Mainstream JavaScript engines

All major browsers implement their own JavaScript engines. Here are some of the major JavaScript engines.

  • Chrome’s V8 engine
  • Firefox SpiderMonkey
  • JavaScriptCore for Safari (also known as Nitro, SquirrelFish, and SquirrelFish Extreme)
  • The Chakra for Edge – but these days the Edge is powered by Chromium V8

JavaScript Engine flowchart

If you’re curious about how JavaScript works, here’s a simple flow chart.

1. The parser

First, the HTML parser encounters aScript tag that contains the JavaScript source code. The source code in this script is loaded into the byte stream decoder as a UTF-16 byte stream. These bytes are decoded into tokens and passed to the parser. To improve efficiency, the engine usually does not parse code that is not temporarily needed.

2. AST

The parser generates nodes based on the tokens it receives, and then generates an abstract syntax tree (AST) based on these nodes. AST plays a crucial role in the semantic analysis phase, when the compiler validates the use of language elements and keywords.

You can visit astexplorer.net/ to see online examples.

3. The interpreter

Next comes the interpreter, which interprets the code line by line, parses the AST, and generates bytecode. After bytecode generation, the AST is removed and the memory space it occupies is emptied. The interpreter can quickly generate unoptimized bytecode and get the program running immediately with no delay.

Note that if the interpreter encounters the same function more than once, it will interpret and execute the function more than once, and the overall efficiency will be slow. That’s why we need a compiler that doesn’t compile in a loop over and over, but runs in a more efficient way.

4. Analysis tools

Analysis tools evaluate running code and identify areas that can be optimized using technology.

5. The compiler

With the help of an analysis tool, any unoptimized code is passed to the compiler for optimization, which produces equally functional but faster machine code that eventually replaces the unoptimized bytecode generated by the previous interpreter.

6. Optimized code

After completing these six steps, you should have highly optimized code.

Now let’s take a quick look at Chrome’s V8 engine and see why it’s so superior.

Chrome’s V8 engine

The V8 engine is an open source application written in C++ that compiles JavaScript code into optimized machine code and then runs it. Originally, the V8 engine was designed to make JavaScript run more efficiently in Chrome and Chromium-based browsers. Over time, recent versions of the V8 engine have been able to take JavaScript code out of the browser, allowing it to be used as server-side scripting.

Early JavaScript engines were interpreters that interpreted code line by line and ran it. But as time went on, this way of running was no longer enough. Chrome V8 implements a technique called just-in-time compilation (JIT), which combines multiple interpreters and compilers for more efficient code execution.

Why is V8 different?

V8 follows the same approach as modern engines like SpiderMonkey and Rhino, but V8 is distinguished by the fact that it doesn’t generate any intermediate code or bytecode.

But that changed in 2016 when the Chrome V8 team launched an interpreter called Ignition. V8, combined with Ignition, compiles JavaScript to shorter bytecodes that are about 50 to 25 percent as long as the same baseline machine code. This bytecode is then run with a high-performance interpreter, which in the real world runs almost as fast as the code generated by V8’s existing baseline compiler.

Rapid change

You have to keep in mind that the Web development landscape is changing fast, especially for browsers. People are constantly trying to improve performance and optimize the experience, which encourages regular tweaks and updates to the JavaScript engine architecture. A blog post will be out of date – it may even be out of date by the time you read this, so IF you want to learn more, I highly recommend checking out the engine’s official documentation.

** In the V8 case, the above pipeline illustration is not up to date. ** The following flowchart shows the current pipeline. Please note that the V8 team is always working on improving engine performance, so this graph may change in the near future.

If you compare the above to the 2016 pipeline diagram, you’ll see that the Baseline section of the pipeline has been completely removed and the crankshafts are gone.

Advantages of the new version pipeline

The V8 team gave many reasons for updating the pipeline, and here are some of them:

  • Reduce memory footprint — Ignition is 8 times smaller than Full-CodeGen in terms of code size.
  • Optimized startup time – bytecode is shorter and can be generated more quickly.
  • Improved baseline performance – Provides extremely efficient code without relying on compiler optimizations.

You can read more from the V8 team here.

V8 new feature development

No JIT-less mode

V8 even has a JIT free mode in which no executable memory is allocated at run time. This mode is useful on iOS, smart TVS, game consoles and other platforms where executable memory cannot be written.

You can read more about it here.

The background to compile

In Chrome 66, V8 uses a background thread to compile JavaScript source code, which can save 5% to 20% on the main thread compilation time on common sites.

Read more in this post on the official blog.


I hope you have a good overview of JavaScript engines. Have fun programming!

data

  • V8 Docs
  • A crash course in just-in-time (JIT) compilers by Lin Clark
  • Article by Sander

If you find any mistakes in your translation or other areas that need to be improved, you are welcome to the Nuggets Translation Program to revise and PR your translation, and you can also get the corresponding reward points. The permanent link to this article at the beginning of this article is the MarkDown link to this article on GitHub.


The Nuggets Translation Project is a community that translates quality Internet technical articles from English sharing articles on nuggets. The content covers Android, iOS, front-end, back-end, blockchain, products, design, artificial intelligence and other fields. If you want to see more high-quality translation, please continue to pay attention to the Translation plan of Digging Gold, the official Weibo, Zhihu column.