缩小 NodeJS 中使用的代码是不是有意义?

Posted

技术标签:

【中文标题】缩小 NodeJS 中使用的代码是不是有意义?【英文标题】:Does it make sense to minify code used in NodeJS?缩小 NodeJS 中使用的代码是否有意义? 【发布时间】:2012-08-17 15:09:20 【问题描述】:

我想知道,由于 Clojure Compiler 和 UglifyJS 不仅针对大小优化代码,而且针对性能优化(尽管我认为大小是主要优先事项),如果我的 node.js 应用程序被缩小,它会运行得更快吗?我知道这可能取决于应用程序,但我一般都是这么问的。

【问题讨论】:

这更像是一个经验性的测试,而不是一个可以明确回答的问题。 我相信它背后有坚实的理论,我只是不明白它......太糟糕了,没有像jsperf这样的工具用于节点...... @João,您可能对***.com/questions/8615577/… 感兴趣。 压缩代码通常是为了节省带宽。既然node.js是在服务器上运行的,那我就说压缩代码没什么意义。 @JoãoPintoJerónimo:如在 jsPerf 上看到的那样 -> npmjs.org/package/benchmark 【参考方案1】:

在 node 中,主要的处理成本是 I/O 操作,而不是实际的 javascript 本身。比如:

fs.readFile(myFile, function (err, data) 
    processTheFile(data);
);

这里,调用readFile 和被触发的回调之间的间隔将比回调所花费的时间长几倍。 (如果反过来,你可能不应该使用节点。)

因此,优化processTheFile 函数以提高速度是没有意义的,因为您节省了非常少数量的一小部分。

【讨论】:

Closure-compiler 的原型去虚拟化和函数内联(连同所有其他优化)将使代码执行得更快,但与 I/O 操作相比,它仍然可能是一个小的改进。跨度> 我见过的最大的胜利实际上是来自折叠属性。 让我直截了当地回答这个问题。我使用 express.js 和 gulp 来缩小我的 webapp 资产,我意识到 app.js 不是资产,它是服务器。我也打算丑化它(app.js)并推入构建目录www/,这是节点http托管,但我认为这篇文章是说节点js服务器文件不需要压缩,这意味着我应该虽然 gulp uglifying 推送到 www/ 却根本不运行它,对吗?我可以在根目录中对其进行 lint,并且只推送客户端内容来构建目录?很高兴将服务器放在 www/ 托管目录之外,无论如何我都喜欢。 是的,没错。在 www 之外拥有服务器不仅“很好”,而且是安全最佳实践。【参考方案2】:

缩小可以提高性能。

Node 的 V8 优化编译器 inlines 根据一些启发式方法运行。缩小会影响这些启发式方法。这可能会导致以前未内联的函数内联。由于内联函数通常执行得更快,因此可以提高性能。

###Node 9.0+ / V8 6.2+ (Turbofan) - 性能小幅提升

如果函数的未优化字节码大小小于 500,它将被内联。缩小通常会减少 AST(抽象语法树)节点数。由于字节码是直接从 AST 生成的,因此我们也可以预期字节码的大小会有所减少。

来源:[Turbofan] Use bytecode size for inlining heuristics.

###Node 8.3+ / V8 5.9+ (Turbofan) → 轻微的性能改进

如果函数的 AST 节点数小于 196,它将被内联。缩小通常会减少 AST 节点数。

来源:[turbofan] Don't take into account source size for inlining heuristics.

###Node 8.2 及之前/V8 5.8(曲轴)及之前 → 主要性能改进

如果函数的字符数(包括空格和 cmets)为 less than 600,它将被内联。

假设我们有一个超过 600 个字符的函数:

function f() 
  // A long comment... bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla bla
  return 1;

缩小到function f()return 1

如果我们现在调用这两个变体 n 次并比较 rawminified 函数的性能,我们会得到以下结果:

显然,缩小后的函数的执行速度是 两倍以上

【讨论】:

【参考方案3】:

不再正确。

是的,Node6 现在基于 v8 5.1,它使用 TurboFan。作为 v8 团队 声明 (https://bugs.chromium.org/p/v8/issues/detail?id=3354) 他们 删除了用于内联的字符计数触发器。

https://medium.com/@c2c/yes-node6-is-now-based-on-v8-5-1-7a645eb9992b https://bugs.chromium.org/p/v8/issues/detail?id=3354

【讨论】:

【参考方案4】:

我创建了一个 nodejs cli,它生成了一个带有一些预定义类的新应用程序。我认为在这种情况下,缩小基本代码是有意义的。因为您希望允许开发人员使用它,但不修改它(或至少让它很难做到)。这样我会推动开发人员下载新版本,而不是更新应用程序中的类。

【讨论】:

以上是关于缩小 NodeJS 中使用的代码是不是有意义?的主要内容,如果未能解决你的问题,请参考以下文章

开发与 iOS 3 兼容的 iPhone 应用程序是不是有意义?

使用 JSLint 并遵循它是不是有意义? [关闭]

对没有 sleep() 的代码使用异步是不是有意义?

如果不使用 onPostExcute,使用 AsyncTask 是不是有意义?

将角度服务与 es6 模块一起使用是不是有意义?

在服务上使用 Vue 3 响应性是不是有意义?