faster.js
faster.js is a Babel plugin that compiles idiomatic Javascript to faster, micro-optimized Javascript.
Installation
Setup Babel for your project if you haven't already. Then install faster.js:
npm install --save-dev faster.js
Usage
.babelrc
Babel CLI
babel-cli --plugins faster.js script.js
webpack.config.js (Webpack 4)
module: rules: test: /\.js$/ exclude: // use: loader: 'babel-loader' options: plugins:
What faster.js does
faster.js rewrites common Array
method calls to faster code that does the same thing (usually - see When NOT to use faster.js). This results in performance boosts (especially on code that relies heavily on Array
methods) while maintaining code readability, but comes at the cost of a slightly larger bundle size. If having a small Javascript bundle size is much more important for you than performance is, you should not use faster.js.
Array
methods
Supported faster.js will rewrite the following Array
methods when possible:
.every()
.filter()
.forEach()
.map()
.reduce()
.reduceRight()
.some()
Demo
Try it yourself: https://fasterjs-demo.victorzhou.com
Demo Github repo: https://github.com/vzhou842/faster.js-demo
⚠️ When NOT to use faster.js
faster.js makes two critical assumptions that MUST be true about your codebase:
Sparse Arrays are never used.
1.Code compiled with faster.js may produce incorrect results when run on sparse arrays.
2. Restricted methods are only ever called on native Javascript arrays:
faster.js assumes any restricted method call is done on a native Javascript array. Any new classes you write should not include methods with restricted names.
Restricted method names are the names of methods that faster.js will attempt to rewrite - see Supported Array
methods.
// OKconst a = 1 2 3; // BAD { this_map = map; } { return this_map; }const f = {};const map = f; // .map() is a restricted method
How faster.js works
faster.js exploits the fact that native Javascript Array
methods are slowed down by having to support seldom-used edge cases like sparse arrays. Assuming no sparse arrays, there are often simple ways to rewrite common Array
methods to improve performance.
Example: Array.prototype.forEach()
// Original codeconst arr = 1 2 3;const results = arr;
roughly compiles to
// Compiled with faster.jsconst arr = 1 2 3;const results = arrlength;const _f = 2 * e;for let _i = 0; _i < arrlength; _i++ results_i = ;
Benchmarks
Example benchmark output (condensed)
$ npm run bench array-every large ✓ native x 2,255,548 ops/sec ±0.46% ✓ faster.js x 10,786,892 ops/sec ±1.25% faster.js is 378.2% faster than native array-filter large ✓ native x 169,237 ops/sec ±1.42% ✓ faster.js x 1,110,629 ops/sec ±1.10% faster.js is 556.3% faster than native array-forEach large ✓ native x 61,097 ops/sec ±3.66% ✓ faster.js x 200,459 ops/sec ±0.52% faster.js is 228.1% faster than native array-map large ✓ native x 179,800 ops/sec ±1.00% ✓ faster.js x 1,706,593 ops/sec ±0.25% faster.js is 849.2% faster than native array-reduce large ✓ native x 200,425 ops/sec ±1.01% ✓ faster.js x 1,694,350 ops/sec ±1.52% faster.js is 745.4% faster than native array-reduceRight large ✓ native x 49,784 ops/sec ±0.38% ✓ faster.js x 1,756,352 ops/sec ±0.99% faster.js is 3428.0% faster than native array-some large ✓ native x 2,968,367 ops/sec ±0.56% ✓ faster.js x 11,591,773 ops/sec ±1.29% faster.js is 290.5% faster than native
The benchmark example above was run on Node 8. Later versions of Node include improvements / optimizations that may make some features in faster.js obsolete. View full benchmark examples here: Node 8, Node 10, Node 12.
FAQ
What is a sparse array?
Sparse arrays are arrays that contain holes or empty slots.
const sparse1 = 0 1; // a sparse array literalconsole; // 3 const sparse2 = ;sparse25 = 0; // sparse2 is now a sparse arrayconsole; // 6
It is generally recommended to avoid using sparse arrays.