dce和tree shaking
为了在弱网环境下降低网络延迟以获取更好的用户体验,我想这些关于如何降低代码体积的技术都是值得研究的。目前降低网络延迟的一个方法是降低js代码的体积,本文研究的就是在压缩代码之前的降低体积的方法——DCE以及Tree Shaking。其实Tree Shaking也可以说是DCE的另一种思路的实现方式。
常规dce
dce 即 dead code elimination(消除死代码),通常在编译阶段由编译器进行判断某些代码是否可达从而删除那些不可能执行的代码,当然由于Javascript没有常规意义上的编译阶段,所以这个工作交由打包工具辅助进行。举个?:
// Some code that cannot be reached
let flag = true; // compiler can't solve this condition
// 对于依赖运行时才能确定是否会使用的代码,DCE和Tree Shaking都没办法处理
if (true && flag) {
// ...
}
else {
// will not execute forever
}
function func () {
return 'result';
// some dead code here;
}
常规的死代码消除一般来说包含上面这几种类型的无用代码,会在打包阶段(一般是uglify.js做的)通过分析去除掉。
tree shaking
俗称摇树优化,直观的说就是将代码中没有使用到的部分通过摇树策略删除掉。为什么称为摇树优化呢?因为这个阶段是在AST中进行的,通过分析将AST中的一些无效分支剪除,看起来就像是将那些死掉的叶子分支摇下来。
好像加粗的那部分有点难以理解,什么叫代码中没有使用到的部分?难道现在程序员写代码时没有用到的代码(函数)还留着没删除?….好吧如果是业务代码这样的话似乎可以理解,这里的Tree Shaking主要是对于第三方库而言的,比如lodash,可能我们项目中只用到了lodash中几个方法,因此多余的那部分代码在打包时也就没必要引入到我们的项目中了。
let a = 'never used'; // never used value
const test = () => {
return 'test func1'
};
// 打包时会将a test删除 因为没有用到
const func = a => b => c => a + b + c;
func();
PS:Tree Shaking只能用于使用es6模块化的项目,主要原因是Tree Shaking是基于ES6模块化机制才能进行代码的静态分析,从而才能进行优化。
参考链接
roll up 作者原文:https://medium.com/@Rich_Harris/tree-shaking-versus-dead-code-elimination-d3765df85c80
百度外卖tree shaking性能优化实践:https://juejin.im/post/5a4dc842518825698e7279a9