【发布时间】:2020-10-06 07:36:25
【问题描述】:
假设您有一个使用一些 JavaScript 库的网站,无论是您自己的还是第三方创作的。除了最小化和混淆之外,我想知道是否可以通过删除未使用的函数来进一步减小脚本有效负载的大小。一旦达到一定程度的复杂性,就很难/不可能知道在所有可能的执行路径下最终调用了哪些函数。这让我产生了一个疑问:有没有什么工具或方法可以确定,在网页使用一段时间后,哪些用户定义的函数(不是内置函数)没有被调用?
一个明显的可能性是将所有函数定义包装在对注册函数的调用中,这 1) 将函数添加到注册器,以及 2) 注入一些代码以将函数标记为已被调用。然后就可以查询那些没有被调用的函数的注册器。然而,这种方法极其复杂。最好的办法是在 Web 服务器上编写一个 JavaScript 代码解析器,它由运行时标志(“处于 JS 诊断模式”)启用,它捕获所有 JavaScript 响应并相应地修改代码。但并不需要太多的想象力就能意识到这将是多么容易出错和困难。
更新:澄清一下,我不是在寻找一个自动删除未使用函数的解决方案,我不会对此感到满意,因为害怕引入不稳定。相反,功能使用的开发时间分析将让我选择要删除的包含/功能,以便最终解决方案可以在发布之前进行适当的测试。
【问题讨论】:
-
这是一个被称为树抖动的问题。 Webpack 包含一些实用程序来促进它。这是一个很大的主题,有很多资源可以帮助解决它。
-
当函数被调用时,可以用一些记录来覆盖 Function.prototype.call。一个简短的实验表明这是可能的。显然,这与最佳实践背道而驰,但无论如何 W3C 都不是我真正的父亲。如果您编译代码库中所有函数的列表,则可以减去被调用函数的列表。
-
@CharlesBamford Monkeypatching
Function.prototype.call无济于事,因为通常直接调用函数。您必须使用其原型call函数调用每个方法。 -
包装所有函数的最简单方法是编写一个 babel-plugin 来转换你的代码,包装每个函数。这应该是相当简单的,你不必接触你的代码库,你可以简单地生成你的代码的两个版本,一个有转换,一个没有。
标签: javascript browser google-chrome-devtools