tree-shaking可以理解为通过工具"摇"我们的JS文件,css文件;将其中用不到的代码"摇"掉,是一个性能优化的范畴。具体来说,在 webpack 项目中,有一个入口文件,相当于一棵树的主干,入口文件有很多依赖的模块,相当于树枝。实际情况中,虽然依赖了某个模块,但其实只使用其中的某些功能。通过 tree-shaking,将没有使用的模块摇掉,这样来达到删除无用代码的目的。
Tree-shaking 较早由 Rich_Harris 的 rollup 实现,后来,webpack2 也增加了tree-shaking 的功能。其实在更早,google closure compiler 也做过类似的事情。三个工具的效果和使用各不相同,使用方法可以通过官网文档去了解。
js ------tree-shaking
tree-shaking的消除原理是依赖于ES6的模块特性
ES6 module 特点:
ES6模块依赖关系是确定的,和运行时的状态无关,可以进行可靠的静态分析,这就是tree-shaking的基础
这是 ES6 modules 在设计时的一个重要考量,也是为什么没有直接采用 CommonJS,正是基于这个基础上,才使得 tree-shaking 成为可能,这也是为什么 rollup 和 webpack 2 都要用 ES6 module syntax 才能 tree-shaking。
然而由于副作用代码;导致并不是那么明显的优化。
副作用
通俗的说-----------一个函数会、或者可能会对函数外部变量产生影响的行为。
首先我们不能确保所写函数都没有副作用;其次就算没有副作用;但是不要忘了 babel编译 + webpack打包
由于babel的编译,一些我们原本看似没有副作用的代码,便转化为了(可能)有副作用的。
具体详细请移步----你的Tree-Shaking并没什么卵用----------写的比较详细。
css ------tree-shaking
css的tree-shaking就是遍历选择器然后与dom结构的选择器和js中匹配,从而去除没有用到的样式代码。
如何优雅的遍历所有的选择器呢?
其实css世界有利器------postCss。
PostCSS 提供了一个解析器,它能够将 CSS 解析成AST抽象语法树。然后我们能写各种插件,对抽象语法树做处理,最终生成新的css文件,以达到对css进行精确修改的目的。
下面说下项目中的具体使用:
purgecss-webpack-plugin助我们进行 CSS Tree Shaking 操作。为了能准确指明要进行 Tree Shaking 的 CSS 文件,搭档glob-all
(另一个第三方库)。glob-all
的作用就是帮助 purgecss 进行路径处理,定位要做 Tree Shaking 的路径文件。
另外推荐使用 使用mini-css-extract-plugin 这个插件(webpack4, 如果版本低于4 是extract-text-webpack-plugin
这个插件)
const PurgecssPlugin = require('purgecss-webpack-plugin');
const glob = require('glob-all');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
new MiniCssExtractPlugin({
filename: 'css/[name].[contenthash:7].css'
}),
new PurgecssPlugin({
paths: glob.sync(
[
path.join(__dirname, './src/**/*.html'),
path.join(__dirname, './src/**/*.js')
]
)
}),
具体打包的css文件,可以自行测试 是有会''摇''掉多余的样式代码。
以上------------------------