{"_id":"optimize-js","_rev":"410366","name":"optimize-js","description":"Optimize initial JavaScript execution/parsing by wrapping eager functions","dist-tags":{"latest":"1.0.3"},"maintainers":[{"name":"aickin","email":"xander76@yahoo.com"},{"name":"krisselden","email":"kris.selden@gmail.com"}],"time":{"modified":"2021-08-04T05:06:25.000Z","created":"2016-09-19T04:51:11.350Z","1.0.3":"2017-01-05T18:15:03.340Z","1.0.2":"2016-10-31T15:40:57.502Z","1.0.1":"2016-09-20T10:34:54.086Z","1.0.0":"2016-09-19T04:51:11.350Z"},"users":{"davidnyhuis":true,"podlebar":true,"b4z81":true,"scottfreecode":true,"cain.chu":true,"xyyjk":true},"author":{"name":"Nolan Lawson","email":"nolan@nolanlawson.com"},"repository":{"type":"git","url":"git+https://github.com/nolanlawson/optimize-js.git"},"versions":{"1.0.3":{"name":"optimize-js","version":"1.0.3","description":"Optimize initial JavaScript execution/parsing by wrapping eager functions","main":"lib/index.js","scripts":{"test":"standard && mocha --timeout 60000 test/test.js","benchmark":"npm run build-benchmark && hs -p 9090 benchmarks","build-benchmark":"sh bin/build-benchmark.sh","publish-benchmark":"sh bin/publish-benchmark.sh","coverage":"istanbul cover ./node_modules/mocha/bin/_mocha test/test.js && istanbul check-coverage --lines 100 --function 100 --statements 100 --branches 100"},"bin":{"optimize-js":"lib/bin.js"},"keywords":["optimize","optimise","js"],"author":{"name":"Nolan Lawson","email":"nolan@nolanlawson.com"},"license":"Apache-2.0","dependencies":{"acorn":"^3.3.0","concat-stream":"^1.5.1","estree-walker":"^0.3.0","magic-string":"^0.16.0","yargs":"^4.8.1"},"devDependencies":{"assert":"^1.4.1","denodeify":"^1.2.1","http-server":"^0.9.0","istanbul":"^0.4.5","mocha":"^3.0.2","standard":"^7.1.2","uglify-js":"^2.7.0"},"files":["lib"],"standard":{"ignore":["test/cases/**","benchmarks/**"]},"repository":{"type":"git","url":"git+https://github.com/nolanlawson/optimize-js.git"},"bugs":{"url":"https://github.com/nolanlawson/optimize-js/issues"},"homepage":"https://github.com/nolanlawson/optimize-js#readme","gitHead":"bbac7678656c85a1e4b98cf22ea4d5342965b2fd","_id":"optimize-js@1.0.3","_shasum":"4326af8657c4a5ff32daf726631754f72ab7fdbc","_from":".","_npmVersion":"3.10.9","_nodeVersion":"7.2.0","_npmUser":{"name":"nolanlawson","email":"nolan@nolanlawson.com"},"dist":{"shasum":"4326af8657c4a5ff32daf726631754f72ab7fdbc","size":11759,"noattachment":false,"key":"/optimize-js/-/optimize-js-1.0.3.tgz","tarball":"http://registry.cnpm.dingdandao.com/optimize-js/download/optimize-js-1.0.3.tgz"},"maintainers":[{"name":"aickin","email":"xander76@yahoo.com"},{"name":"krisselden","email":"kris.selden@gmail.com"}],"_npmOperationalInternal":{"host":"packages-18-east.internal.npmjs.com","tmp":"tmp/optimize-js-1.0.3.tgz_1483640101292_0.7137674775440246"},"directories":{},"publish_time":1483640103340,"_cnpm_publish_time":1483640103340,"_hasShrinkwrap":false},"1.0.2":{"name":"optimize-js","version":"1.0.2","description":"Optimize initial JavaScript execution/parsing by wrapping eager functions","main":"lib/index.js","scripts":{"test":"standard && mocha test/test.js","benchmark":"npm run build-benchmark && hs -p 9090 benchmarks","build-benchmark":"sh bin/build-benchmark.sh","publish-benchmark":"sh bin/publish-benchmark.sh","coverage":"istanbul cover ./node_modules/mocha/bin/_mocha test/test.js && istanbul check-coverage --lines 100 --function 100 --statements 100 --branches 100"},"bin":{"optimize-js":"lib/bin.js"},"keywords":["optimize","optimise","js"],"author":{"name":"Nolan Lawson","email":"nolan@nolanlawson.com"},"license":"Apache-2.0","dependencies":{"acorn":"^3.3.0","concat-stream":"^1.5.1","estree-walker":"^0.3.0","magic-string":"^0.16.0","yargs":"^4.8.1"},"devDependencies":{"assert":"^1.4.1","denodeify":"^1.2.1","http-server":"^0.9.0","istanbul":"^0.4.5","mocha":"^3.0.2","standard":"^7.1.2","uglify-js":"^2.7.0"},"files":["lib"],"standard":{"ignore":["test/cases/**","benchmarks/**"]},"repository":{"type":"git","url":"git+https://github.com/nolanlawson/optimize-js.git"},"bugs":{"url":"https://github.com/nolanlawson/optimize-js/issues"},"homepage":"https://github.com/nolanlawson/optimize-js#readme","gitHead":"01140ceed6b09e320f5704f41ab8d6c9f5ec1f41","_id":"optimize-js@1.0.2","_shasum":"1c5b8fd33ea9bd7fa3e4ecc0a9efa7e95f372907","_from":".","_npmVersion":"3.10.3","_nodeVersion":"6.7.0","_npmUser":{"name":"nolanlawson","email":"nolan@nolanlawson.com"},"dist":{"shasum":"1c5b8fd33ea9bd7fa3e4ecc0a9efa7e95f372907","size":10685,"noattachment":false,"key":"/optimize-js/-/optimize-js-1.0.2.tgz","tarball":"http://registry.cnpm.dingdandao.com/optimize-js/download/optimize-js-1.0.2.tgz"},"maintainers":[{"name":"aickin","email":"xander76@yahoo.com"},{"name":"krisselden","email":"kris.selden@gmail.com"}],"_npmOperationalInternal":{"host":"packages-12-west.internal.npmjs.com","tmp":"tmp/optimize-js-1.0.2.tgz_1477928457290_0.38781770039349794"},"directories":{},"publish_time":1477928457502,"_cnpm_publish_time":1477928457502,"_hasShrinkwrap":false},"1.0.1":{"name":"optimize-js","version":"1.0.1","description":"Optimize JavaScript execution by wrapping eager functions","main":"lib/index.js","scripts":{"test":"standard && mocha test/test.js","benchmark":"npm run build-benchmark && hs -p 9090 benchmarks","build-benchmark":"sh bin/build-benchmark.sh","publish-benchmark":"sh bin/publish-benchmark.sh","coverage":"istanbul cover ./node_modules/mocha/bin/_mocha test/test.js && istanbul check-coverage --lines 100 --function 100 --statements 100 --branches 100"},"bin":{"optimize-js":"lib/bin.js"},"keywords":["optimize","optimise","js"],"author":{"name":"Nolan Lawson","email":"nolan@nolanlawson.com"},"license":"Apache-2.0","dependencies":{"acorn":"^3.3.0","concat-stream":"^1.5.1","magic-string":"^0.16.0","walk-ast":"^0.0.2","yargs":"^4.8.1"},"devDependencies":{"assert":"^1.4.1","denodeify":"^1.2.1","http-server":"^0.9.0","istanbul":"^0.4.5","mocha":"^3.0.2","standard":"^7.1.2","uglify-js":"^2.7.0"},"files":["lib"],"standard":{"ignore":["test/cases/**","benchmarks/**"]},"repository":{"type":"git","url":"git+https://github.com/nolanlawson/optimize-js.git"},"bugs":{"url":"https://github.com/nolanlawson/optimize-js/issues"},"homepage":"https://github.com/nolanlawson/optimize-js#readme","gitHead":"e5756fe7a262957a2839450ca4122f11ddfa9a76","_id":"optimize-js@1.0.1","_shasum":"aeab577b80ee3b140d832517971b3cd04f0a7740","_from":".","_npmVersion":"3.10.3","_nodeVersion":"6.3.0","_npmUser":{"name":"nolanlawson","email":"nolan@nolanlawson.com"},"dist":{"shasum":"aeab577b80ee3b140d832517971b3cd04f0a7740","size":10413,"noattachment":false,"key":"/optimize-js/-/optimize-js-1.0.1.tgz","tarball":"http://registry.cnpm.dingdandao.com/optimize-js/download/optimize-js-1.0.1.tgz"},"maintainers":[{"name":"aickin","email":"xander76@yahoo.com"},{"name":"krisselden","email":"kris.selden@gmail.com"}],"_npmOperationalInternal":{"host":"packages-16-east.internal.npmjs.com","tmp":"tmp/optimize-js-1.0.1.tgz_1474367692018_0.42548557301051915"},"directories":{},"publish_time":1474367694086,"_cnpm_publish_time":1474367694086,"_hasShrinkwrap":false},"1.0.0":{"name":"optimize-js","version":"1.0.0","description":"Optimize JavaScript execution by wrapping eager functions","main":"lib/index.js","scripts":{"test":"standard && mocha test/test.js","benchmark":"npm run build-benchmark && hs -p 9090 benchmarks","build-benchmark":"sh bin/build-benchmark.sh","publish-benchmark":"sh bin/publish-benchmark.sh","coverage":"istanbul cover ./node_modules/mocha/bin/_mocha test/test.js && istanbul check-coverage --lines 100 --function 100 --statements 100 --branches 100"},"bin":{"optimize-js":"lib/bin.js"},"keywords":["optimize","optimise","js"],"author":{"name":"Nolan Lawson","email":"nolan@nolanlawson.com"},"license":"Apache-2.0","dependencies":{"acorn":"^3.3.0","concat-stream":"^1.5.1","magic-string":"^0.16.0","walk-ast":"^0.0.2","yargs":"^4.8.1"},"devDependencies":{"assert":"^1.4.1","denodeify":"^1.2.1","http-server":"^0.9.0","istanbul":"^0.4.5","mocha":"^3.0.2","standard":"^7.1.2","uglify-js":"^2.7.0"},"files":["lib"],"standard":{"ignore":["test/cases/**","benchmarks/**"]},"repository":{"type":"git","url":"git+https://github.com/nolanlawson/optimize-js.git"},"bugs":{"url":"https://github.com/nolanlawson/optimize-js/issues"},"homepage":"https://github.com/nolanlawson/optimize-js#readme","gitHead":"2a555f478704edc9e334becc60a910476ce2a7be","_id":"optimize-js@1.0.0","_shasum":"0973ea8f87f893d5c6a1d4558a36fa91567c773d","_from":".","_npmVersion":"3.10.7","_nodeVersion":"6.5.0","_npmUser":{"name":"nolanlawson","email":"nolan@nolanlawson.com"},"dist":{"shasum":"0973ea8f87f893d5c6a1d4558a36fa91567c773d","size":10468,"noattachment":false,"key":"/optimize-js/-/optimize-js-1.0.0.tgz","tarball":"http://registry.cnpm.dingdandao.com/optimize-js/download/optimize-js-1.0.0.tgz"},"maintainers":[{"name":"aickin","email":"xander76@yahoo.com"},{"name":"krisselden","email":"kris.selden@gmail.com"}],"_npmOperationalInternal":{"host":"packages-12-west.internal.npmjs.com","tmp":"tmp/optimize-js-1.0.0.tgz_1474260669211_0.07124660792760551"},"directories":{},"publish_time":1474260671350,"_cnpm_publish_time":1474260671350,"_hasShrinkwrap":false}},"readme":"optimize-js [![Build Status](https://travis-ci.org/nolanlawson/optimize-js.svg?branch=master)](https://travis-ci.org/nolanlawson/optimize-js) [![JavaScript Style Guide](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](http://standardjs.com/)\n========\n\nOptimize a JavaScript file for faster initial execution and parsing, by wrapping all immediately-invoked functions or likely-to-be-invoked functions in parentheses.\n\nSee the [changelog](#changelog) for recent changes.\n\nInstall\n---\n\n    npm install -g optimize-js\n\nUsage\n---\n\n    optimize-js input.js > output.js\n\nExample input:\n\n```js\n!function (){}()\nfunction runIt(fun){ fun() }\nrunIt(function (){})\n```\n\nExample output:\n\n```js\n!(function (){})()\nfunction runIt(fun){ fun() }\nrunIt((function (){}))\n```\n\nBenchmark overview\n----\n\n| Browser | Typical speed boost/regression using optimize-js |\n| ---- | ----- |\n| Chrome 55 | 20.63% |\n| Edge 14 | 13.52% |\n| Firefox 50 | 8.26% |\n| Safari 10 | -1.04% |\n\nThese numbers are based on a benchmark of common JS libraries. For benchmark details, see [benchmarks](#benchmarks).\n\nCLI\n----\n\n```\nUsage: optimize-js [ options ]\n\nOptions:\n  --source-map  include source map                                     [boolean]\n  -h, --help    Show help                                              [boolean]\n\nExamples:\n  optimize-js input.js > output.js    optimize input.js\n  optimize-js < input.js > output.js  read from stdin, write to stdout\n```\n\nJavaScript API\n----\n\n```js\nvar optimizeJs = require('optimize-js');\nvar input = \"!function() {console.log('wrap me!')}\";\nvar output = optimizeJs(input); // \"!(function() {console.log('wrap me!')})()\"\n```\n\nYou can also pass in arguments:\n```js\nvar optimizeJs = require('optimize-js');\nvar input = \"!function() {console.log('wrap me!')}\";\nvar output = optimizeJs(input, {\n  sourceMap: true\n}); // now the output has source maps\n```\n\nWhy?\n----\n\nModern JavaScript engines like V8, Chakra, and SpiderMonkey have a heuristic where they pre-parse most \nfunctions before doing a full parse.\nThe pre-parse step merely checks for syntax errors while avoiding the cost of a full parse.\n\nThis heuristic is based on the assumption that, on the average web page, most JavaScript functions are never\nexecuted or are lazily executed.\nSo a pre-parse can prevent a slower startup time by only checking for what the browser absolutely needs\nto know about the function (i.e. whether it's syntactically well-formed or not).\n\nUnfortunately this assumption breaks down in the case of immediately-invoked function expressions (IIFEs), such as these:\n\n```js\n(function () { console.log('executed!') })();\n(function () { console.log('executed Crockford-style!') }());\n!function () { console.log('executed UglifyJS-style!') }();\n```\n\nThe good news is that JS engines have a _further_ optimization,\nwhere they try to detect such IIFEs and skip the pre-parse step. Hooray!\n\nThe bad news, though, is that these heuristics don't always work,\nbecause they're based on a greedy method of checking for a `'('` token immediately to the left of the function. (The parser\navoids anything more intricate because it would amount to parsing the whole thing, negating the benefit of the pre-parse). \nIn cases without the paren (which include\ncommon module formats like UMD/Browserify/Webpack/etc.), the browser will actually parse the function _twice_, first as a pre-parse and second\nas a full parse. This means that the JavaScript code runs much more slowly overall, because more time is spent parsing than needs to be. See [\"The cost of small modules\"](https://nolanlawson.com/2016/08/15/the-cost-of-small-modules/) for an idea of how bad this can get.\n\nLuckily, because the `'('` optimization for IIFEs is so well-established, we can exploit this during our build process by\nparsing the entire JavaScript file in advance (a luxury the browser can't afford) and inserting parentheses in the cases where we _know_\nthe function will be immediately executed (or where we have a good hunch). That's what `optimize-js` does.\n\nMore details on the IIFE optimization can be found in [this discussion](https://github.com/mishoo/UglifyJS2/issues/886). Some of my thoughts on the virtues of compile-time optimizations can be found in [this post](https://gist.github.com/nolanlawson/e73c61da78ffb39e4fc034a62ce8b263).\n\nFAQs\n----\n\n### How does it work?\n\nThe current implementation is to parse to a syntax tree and check for functions that:\n\n1. Are immediately-invoked via any kind of call statement (`function(){}()`, `!function(){}()`, etc.)\n2. Are passed in directly as arguments to another function\n\nThe first method is an easy win – those functions are immediately executed. The second method is more of a heuristic, but tends\nto be a safe bet given common patterns like Node-style errbacks, Promise chains, and UMD/Browserify/Webpack module declarations. \n\nIn all such cases, `optimize-js` wraps the function in parentheses.\n\n### But... you're adding bytes!\n\nYes, `optimize-js` might add as many as two bytes (horror!) per function, which amounts to practically nil once you\ntake gzip into account. To prove it, here are the gzipped sizes for the libraries I use in the benchmark:\n\n| Script | Size (bytes) | Difference (bytes) |\n| ---- | --- | --- |\n| benchmarks/create-react-app.min.js | 160387 ||\n| benchmarks/create-react-app.min.optimized.js | 160824 |+ 437 |\n| benchmarks/immutable.min.js | 56738 ||\n| benchmarks/immutable.min.optimized.js | 56933 |+ 195 |\n| benchmarks/jquery.min.js | 86808 ||\n| benchmarks/jquery.min.optimized.js | 87109 |+ 301 |\n| benchmarks/lodash.min.js | 71381 ||\n| benchmarks/lodash.min.optimized.js | 71644 |+ 263 |\n| benchmarks/pouchdb.min.js | 140332 ||\n| benchmarks/pouchdb.min.optimized.js | 141231 |+ 899 |\n| benchmarks/three.min.js | 486996 ||\n| benchmarks/three.min.optimized.js | 487279 |+ 283 |\n\n### Is `optimize-js` intended for library authors?\n\nSure! If you are already shipping a bundled, minified version of your library, then there's no reason not to apply `optimize-js` (assuming you benchmark your code to ensure it does indeed help!). However, note that `optimize-js` should run _after_ Uglify, since Uglify strips extra parentheses and also [negates IIFEs by default](https://github.com/mishoo/UglifyJS2/issues/640). This also means that if your users apply Uglification to your bundle, then the optimization will be undone.\n\nAlso note that because `optimize-js` optimizes for some patterns that are based on heuristics rather than _known_ eagerly-invoked\nfunctions, it may actually hurt your performance in some cases. (See benchmarks below for examples.) Be sure to check that `optimize-js` is a help rather than a hindrance for your particular codebase, using something like:\n\n```html\n<script>\nvar start = performance.now();\n</script>\n<script src=\"myscript.js\"></script>\n<script>\nvar end = performance.now();\nconsole.log('took ' + (end - start) + 'ms');\n</script>\n```\n\nNote that the script boundaries are actually recommended, in order to truly measure the full parse/compile time.\nIf you'd like to avoid measuring the network overhead, you can see how we do it in [our benchmarks](https://github.com/nolanlawson/optimize-js/tree/master/benchmarks).\n\nYou may also want to check out [marky](http://github.com/nolanlawson/marky),\nwhich allows you to easily set mark/measure points that you can visually inspect in the Dev Tools timeline to ensure that the full\ncompile time is being measured.\n\nAlso, be sure to test in multiple browsers! If you need an Edge VM, check out [edge.ms](http://edge.ms).\n\n### Shouldn't this be Uglify's job?\n\nPossibly! This is a free and open-source library, so I encourage anybody to borrow the code or the good ideas. :)\n\n### Why not paren-wrap every single function?\n\nAs described above, the pre-parsing optimization in browsers is a very good idea for the vast majority of the web, where most functions \naren't immediately executed. However, since `optimize-js` knows when your functions are immediately executed (or can make reasonable\nguesses), it can be more judicious in applying the paren hack.\n\n### Does this really work for every JavaScript engine?\n\nBased on my tests, this optimization seems to work best for V8 (Chrome), followed by Chakra (Edge), followed by SpiderMonkey (Firefox). For JavaScriptCore (Safari) it seems to be basically a wash, and may actually be a slight regression overall depending on your codebase. (Again, this is why it's important to actually measure on your own codebase, on the browsers you actually target!)\n\nIn the case of Chakra, [Uglify-style IIFEs are actually already optimized](https://github.com/mishoo/UglifyJS2/issues/640#issuecomment-247792319), but using `optimize-js` doesn't hurt because a\nfunction preceded by `'('` still goes into the fast path.\n\nBenchmarks\n----\n\nThese tests were run using a handful of popular libraries, wrapped in `performance.now()` measurements. Each test reported the median of 251 runs. `optimize-js` commit [da51013](https://github.com/nolanlawson/optimize-js/commit/da51013) was tested. Minification was applied using `uglifyjs -mc`, Uglify 2.7.0.\n\nYou can also try [a live version of the benchmark](https://nolanlawson.github.io/optimize-js/).\n\n### Chrome 55, Windows 10 RS1, Surfacebook i5\n\n| Script | Original | Optimized | Improvement | Minified | Min+Optimized | Improvement |\n| ---- | ---- | ---- | ---- | ---- | ---- | ---- |\n| Create React App | 55.39ms | 51.71ms | **6.64%** | 26.12ms | 21.09ms | **19.26%** |\n| ImmutableJS | 11.61ms | 7.95ms | **31.50%** | 8.50ms | 5.99ms | **29.55%** |\n| jQuery | 22.51ms | 16.62ms | **26.18%** | 19.35ms | 16.10ms | **16.80%** |\n| Lodash | 20.88ms | 19.30ms | **7.57%** | 20.47ms | 19.86ms | **3.00%** |\n| PouchDB | 43.75ms | 20.36ms | **53.45%** | 36.40ms | 18.78ms | **48.43%** |\n| ThreeJS | 71.04ms | 72.98ms | **-2.73%** | 54.99ms | 39.59ms | **28.00%** |\nOverall improvement: **20.63%**\n\n### Edge 14, Windows 10 RS1, SurfaceBook i5\n\n| Script | Original | Optimized | Improvement | Minified | Min+Optimized | Improvement |\n| ---- | ---- | ---- | ---- | ---- | ---- | ---- |\n| Create React App | 32.46ms | 24.85ms | **23.44%** | 26.49ms | 20.39ms | **23.03%** |\n| ImmutableJS | 8.94ms | 6.19ms | **30.74%** | 7.79ms | 5.41ms | **30.55%** |\n| jQuery | 22.56ms | 14.45ms | **35.94%** | 16.62ms | 12.99ms | **21.81%** |\n| Lodash | 22.16ms | 21.48ms | **3.05%** | 15.77ms | 15.46ms | **1.96%** |\n| PouchDB | 24.07ms | 21.22ms | **11.84%** | 39.76ms | 52.86ms | **-32.98%** |\n| ThreeJS | 43.77ms | 39.99ms | **8.65%** | 54.00ms | 36.57ms | **32.28%** |\nOverall improvement: **13.52%**\n\n### Firefox 50, Windows 10 RS1, Surfacebook i5\n\n| Script | Original | Optimized | Improvement | Minified | Min+Optimized | Improvement |\n| ---- | ---- | ---- | ---- | ---- | ---- | ---- |\n| Create React App | 33.56ms | 28.02ms | **16.50%** | 24.71ms | 22.05ms | **10.76%** |\n| ImmutableJS | 6.52ms | 5.75ms | **11.80%** | 4.96ms | 4.58ms | **7.47%** |\n| jQuery | 15.77ms | 13.97ms | **11.41%** | 12.90ms | 12.15ms | **5.85%** |\n| Lodash | 17.08ms | 16.63ms | **2.64%** | 13.11ms | 13.22ms | **-0.80%** |\n| PouchDB | 19.23ms | 16.77ms | **12.82%** | 13.77ms | 12.89ms | **6.42%** |\n| ThreeJS | 38.33ms | 37.36ms | **2.53%** | 33.01ms | 30.32ms | **8.16%** |\nOverall improvement: **8.26%**\n\n### Safari 10, macOS Sierra, 2013 MacBook Pro i5\n\n| Script | Original | Optimized | Improvement | Minified | Min+Optimized | Improvement |\n| ---- | ---- | ---- | ---- | ---- | ---- | ---- |\n| Create React App | 31.60ms | 31.60ms | **0.00%** | 23.10ms | 23.50ms | **-1.73%** |\n| ImmutableJS | 5.70ms | 5.60ms | **1.75%** | 4.50ms | 4.50ms | **0.00%** |\n| jQuery | 12.40ms | 12.60ms | **-1.61%** | 10.80ms | 10.90ms | **-0.93%** |\n| Lodash | 14.70ms | 14.50ms | **1.36%** | 11.10ms | 11.30ms | **-1.80%** |\n| PouchDB | 14.00ms | 14.20ms | **-1.43%** | 11.70ms | 12.10ms | **-3.42%** |\n| ThreeJS | 35.60ms | 36.30ms | **-1.97%** | 27.50ms | 27.70ms | **-0.73%** |\nOverall improvement: **-1.04%**\n\nNote that these results may vary based on your machine, how taxed your CPU is, gremlins, etc. I ran the full suite a few times on all browsers and found these numbers to be roughly representative. In our test suite, we use a median of 151 runs to reduce variability.\n\nPlugins\n---\n\n* [Grunt plugin for optimize-js](https://github.com/sergejmueller/grunt-optimize-js)\n* [Gulp plugin for optimize-js](https://github.com/prateekbh/gulp-optimize-js)\n* [Webpack plugin for optimize-js](https://github.com/vigneshshanmugam/optimize-js-plugin)\n\nSee also\n---\n\n* [broccoli-ember-preparse](https://www.npmjs.com/package/broccoli-ember-preparse)\n* [to-fast-properties](https://github.com/sindresorhus/to-fast-properties)\n* [V8LazyParsePlugin](https://github.com/TheLarkInn/V8LazyParseWebpackPlugin)\n\nThanks\n----\n\nThanks to [@krisselden](https://github.com/krisselden), [@bmaurer](https://github.com/bmaurer), and [@pleath](https://github.com/pleath) for explaining these concepts in the various GitHub issues. Thanks also to [astexplorer](https://github.com/fkling/astexplorer), [acorn](https://github.com/ternjs/acorn), and [magic-string](https://www.npmjs.com/package/magic-string) for making the implementation so easy.\n\nThanks to [Sasha Aickin](https://github.com/aickin) for generous contributions to improving this library (especially in v1.0.3)\nand prodding me to improve the accuracy of the benchmarks.\n\nContributing\n-----\n\nBuild and run tests:\n\n```bash\nnpm install\nnpm test\n```\n\nRun the benchmarks:\n\n```bash\nnpm run benchmark # then open localhost:9090 in a browser\n```\n\nTest code coverage:\n\n```bash\nnpm run coverage\n```\n\nChangelog\n----\n\n- v1.0.3\n  - Much more accurate benchmark (#37)\n  - Browserify-specific fixes (#29, #36, #39)\n  - Webpack-specific fixes (#7, #34)\n- v1.0.2\n  - Use estree-walker to properly parse ES6 (#31)\n- v1.0.1:\n  - Don't call process.exit(0) on success (#11)\n- v1.0.0\n  - Initial release\n","_attachments":{},"homepage":"https://github.com/nolanlawson/optimize-js#readme","bugs":{"url":"https://github.com/nolanlawson/optimize-js/issues"},"license":"Apache-2.0"}