Published by Oliver

• 4 min read

Introduction

Prepack is currently the new shiny toy in the world of Javascript. It aims to reduce initialization time of JavaScript code, by eliminating computations which can be done at compile-time instead of run-time. Prepack is all about the initialization phase of the code. It replaces the global code of a JavaScript bundle with equivalent code that is a simple sequence of assignments. This gets rid of most intermediate computations and object allocations, which means faster load times. Sometimes up to 10 times!

Made by Facebook Open Source, a compiler which uses Babel to parse and generate JavaScript source code, with an almost ECMAScript 5 compatible interpreter. Nikolaj Tillman who joined Facebook to work on this particular project wrote:

“Prepack is quite complementary to traditional compilers. Its strength is that it comes with full knowledge of the JavaScript built-ins, and it uses that to pre-evaluate the code at compile time. In an extreme case, an entire program can get reduced to the final result.”

Example

You can try Prepack online here.

Inside Prepack

Prepack operates at the Abstract Syntax Tree level, using Babel to parse and generate JavaScript source code.

At its core is an ECMAScript 5 compatible interpreter — implemented in JavaScript! It runs the given code, creating a snapshot and then recreating JavaScript code accordingly.

In addition to computing over concrete values, Prepack’s interpreter has the ability to operate on abstract values which typically arise from environment interactions.

At the end of the initialization phase when the global code returns, Prepack captures the final heap. Prepack walks the heap in order, generating fresh straightforward JavaScript code that creates and links all objects reachable in the initialized heap. Some of the values in the heap might be result of computations over abstract values. For those values, Prepack generates code that performs those computations as the original program would.

Usage

Prepack is still in development phase and doesn’t work with major front-end frameworks or the DOM. It has no clue about window or document objects, yet. That’s why its usage is still limited. We were able to test Prepack on some of the popular JavaScript libraries, but it’s nowhere production ready.

Some libs had to be tweaked in order to work with Prepack. For example, y++; is not supported on abstract numbers but y = y + 1; works just fine.

Each library was loaded on empty website from a localhost server. An average was computed out of the scripting time consumed by JavaScript initialization phase. Times were compared to the Prepacked version and original. In three cases ( Bluebird, RxJS, Underscore ) Prepack performed really well, in others not so much. Why is that you may ask?

Well, some libs are really good written and their initialization phase is quite simple and fast already. On top of that, Prepack adds type checking when working with abstract values, which may increase total lines of code and logic involved.

Before

After

It’s always good to test new tools and find out if it suits your use case, like in Bluebird or RxJS case where it helped to speed up initialization time.

Conclusion

Although Prepack tries to speed up the web, it’s still in development and not ready for most of the web apps. One of the more welcoming features is DOM shims. This would allow Prepack to work with browsers DOM API and truly reduce initialization time of JavaScript code.

The short term goals for Prepack are more integration with React Native toolchain where we will see any improvements the most soon. After that, we can expect Prepack team to work on the web and node.js environments. There is still a long road ahead. If you would like to help feel free to do so on the GitHub repository.