Another big story from Facebook!

Early this morning, a tool called Prepack overwhelmed social media.

Prepack. IO is the most powerful tool in the world, so it is necessary to introduce it to you at the first time.

If you look at the name “Prepack,” it must be doing something to the code before it’s released (” Pre “). The website describes Prepack as “a tool to make JavaScript run faster.” So what does it do?

According to its home page, Prepack “eliminates run-time calculations that could have been done during the compile phase,” replacing parts of the code with a series of assignments, thus saving a lot of intermediate calculations and object assignments.

The official sample

Here’s an example from Prepack’s website:

(function () {

  var self = this;

  ['A', 'B', 42].forEach(function(x) {

    var name = '_' + x.toString()[0].toLowerCase();

    var y = parseInt(x);

    self[name] = y ? y : x;

  });

}) ();

With Prepack, the above code looks like this:

(function () {

  _a = "A";

  _b = "B";

  _4 = 42;

}) ();

The original.foreach call is gone, along with a series of intermediate conversions. To borrow from the official website, “most calculations are pre-initialized when Prepack is compiled.”

Here’s another example from Fibonacci:

/ / before processing

(function () {

  function fibonacci(x) {

    return x <= 1 ? x : fibonacci(x - 1) + fibonacci(x - 2);

  }

  global.x = fibonacci(23);

}) ();



/ / after processing

(function () {

  x = 28657;

}) ();

Working mechanism

Prepack relies on the following aspects:

1. AST (Abstract Syntax tree)

Prepack operates on code at the AST level. Babel is used to parse the source code and generate optimized code.

About Babel and AST, I recommend two articles:

  • Babel for ES6? And Beyond!

  • Understand AST by developing the Babel plug-in

2. Concrete Execution

The core of Prepack is “an almost ECMAScript 5 Compatible interpreter,” which is implemented through JavaScript. The compiler can track and undo all operations, including object changes. This way we support speculative Optimizations.

3. Symbolic Execution

In addition to calculating concrete values, Prepack’s compiler can also manipulate abstract values, which are often derived from code’s interaction with the environment. Returns such as date.now are abstract values. In addition, you can manually insert abstract values through helper functions such as __abstract(), as described on the front page of the official website. Prepack keeps track of operations that occur on an abstract value, and probes all possibilities if there is a branching case.

“As a result, Prepack implements a symbolic execution engine for JavaScript,” the website says. To make things easier for you, the weekly quoted a passage from Wikipedia:

Symbolic Execution is a program analysis technique. It can be parsed to get input for a particular area of code to execute. When analyzing a program using symbolic execution, the program uses symbolic values as input, rather than the specific values used in the general execution of the program. When the object code is reached, the analyzer can obtain the corresponding path constraint, and then use the constraint solver to obtain the specific value that can trigger the object code.

4. Abstract Interpretation

The description on the website is a bit complicated. For an abstract explanation, go to Wikipedia. Those who are interested can go to the official website to read the original article.

5. Heap Serialization

At the end of the initialization phase, Prepack captures the final heap. Traverse the heap sequentially, generating new code, creating and linking reachable objects in the heap.

As mentioned earlier, some of the values in the heap may be the result of a calculation of abstract values. Prepack will generate the code to perform the calculation based on these values, using the same calculation process as the source program.

Context is important!

It is important to note that Prepack does not fully emulate the browser and Node environment, and Prepack does not know much about Document and Window. When you evaluate some of these properties, you get undefined. If you need to use Prepack in such places, you must do so through utility functions.

How to try

# installation

npm install -g prepack



Process the file and print it to the console

prepack script.js



# process the file and print it to a new file

prepack script.js --out script-processed.js

In addition to the basic usage above, more options such as sourceMap are supported. I don’t want to introduce them here.

Current Support

Prepack does not yet support parameter expansion, module.exports, etc., and const is ignored.

For more information on the Roadmap for discovery, visit the Roadmap section on the homepage.

“Prepack is still in the early stages of development and is not yet ready for production,” the company said. Instead, heed Prepack’s call to “try it out, give feedback, and help fix bugs.”

Related technologies

Closure Compiler also optimizes JavaScript code. Prepack goes further than the Closure Compiler by executing the initialization phase of global code, unrolling loops and recursion. “Prepack focuses on runtime performance, whereas Closure Compiler focuses on code size,” reads a statement on the website.