[关闭]
@lenville 2017-05-04T14:07:12.000000Z 字数 3431 阅读 643

Facebook开源JavaScript代码优化工具Prepack

Facebook JavaScript Prepack


5月4日,Facebook开源团队技术作者Joel Marcey在Hacker News社区发布一则《Prepack帮助提高JavaScript代码的效率》,引起了社区的广泛讨论

官方宣称Prepack是一个优化JavaScript源代码的工具,实际上它是一个JavaScript的部分求值器(Partial Evaluator),可在编译时执行原本在运行时的计算过程,并通过重写JavaScript代码来提高其执行效率。Prepack用简单的赋值序列来等效替换JavaScript代码包中的全局代码,从而消除了中间计算过程以及对象分配的操作。对于重初始化的代码,Prepack可以有效缓存JavaScript解析的结果,优化效果最佳。

以下五个概念可以帮助你更好地理解Prepack的运行机制:

以下是官方提供的Prepack优化示例:

  1. /* Hello World */
  2. // Input
  3. (function () {
  4. function hello() { return 'hello'; }
  5. function world() { return 'world'; }
  6. global.s = hello() + ' ' + world();
  7. })();
  8. // Output
  9. (function () {
  10. s = "hello world";
  11. })();
  1. /* 消除抽象税 */
  2. // Input
  3. (function () {
  4. var self = this;
  5. ['A', 'B', 42].forEach(function(x) {
  6. var name = '_' + x.toString()[0].toLowerCase();
  7. var y = parseInt(x);
  8. self[name] = y ? y : x;
  9. });
  10. })();
  11. // Output
  12. (function () {
  13. _a = "A";
  14. _b = "B";
  15. _4 = 42;
  16. })();
  1. /* 斐波那契 */
  2. // Input
  3. (function () {
  4. function fibonacci(x) {
  5. return x <= 1 ? x : fibonacci(x - 1) + fibonacci(x - 2);
  6. }
  7. global.x = fibonacci(23);
  8. })();
  9. // Output
  10. (function () {
  11. x = 28657;
  12. })();
  1. /* 模块初始化 */
  2. // Input
  3. (function () {
  4. let moduleTable = {};
  5. function define(id, f) { moduleTable[id] = f; }
  6. function require(id) {
  7. let x = moduleTable[id];
  8. return x instanceof Function ? (moduleTable[id] = x()) : x;
  9. }
  10. global.require = require;
  11. define("one", function() { return 1; });
  12. define("two", function() { return require("one") + require("one"); });
  13. define("three", function() { return require("two") + require("one"); });
  14. define("four", function() { return require("three") + require("one"); });
  15. })();
  16. three = require("three");
  17. // Output
  18. (function () {
  19. function _2() {
  20. return 3 + 1;
  21. }
  22. var _1 = {
  23. one: 1,
  24. two: 2,
  25. three: 3,
  26. four: _2
  27. };
  28. function _0(id) {
  29. let x = _1[id];
  30. return x instanceof Function ? _1[id] = x() : x;
  31. }
  32. require = _0;
  33. three = 3;
  34. })();
  1. /* 环境相互作用与分支 */
  2. // Input
  3. (function(){
  4. function fib(x) { return x <= 1 ? x : fib(x - 1) + fib(x - 2); }
  5. let x = Date.now();
  6. if (x === 0) x = fib(10);
  7. global.result = x;
  8. })();
  9. // Output
  10. (function () {
  11. var _0 = Date.now();
  12. if (typeof _0 !== "number") {
  13. throw new Error("Prepack model invariant violation");
  14. }
  15. result = _0 === 0 ? 55 : _0;
  16. })();

目前Prepack仍处于早期开发阶段,尚未准备好在生产环境中使用,官方建议仅尝试使用,并欢迎提供反馈以帮助修复错误。

以下是Prepack团队对未来的规划:

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注