跳至内容
欢迎 Web Awesome,最大的开源 Web 组件库。
立即预订!

树状抖动

使用树状抖动自动对图标进行子集化并仅包含您正在使用的图标。

从 Rich Harris 的出色工具 Rollup.js 开始,树状抖动的概念试图消除任何未使用的代码。Webpack 2 现在也包含了此功能。

使用 Font Awesome 进行树状抖动

Font Awesome 图标包开箱即用地支持树状抖动,但仅当您的工具与树状抖动兼容时

在此示例中,仅从 free-solid-svg-icons 导入 faCoffee,因此仅该图标将包含在生产优化捆绑包中

// Tree-shaking Example
import {faCoffee} from '@fortawesome/free-solid-svg-icons'

树状抖动的替代方案:深度导入

如果您的工具尚不支持树状抖动,您仍然可以通过遵循以下示例来从仅导入您使用的图标中获益

// Bullet-proof deep import example
import { faCoffee } from '@fortawesome/free-solid-svg-icons/faCoffee' // <-- note the extra faCoffee there

树状抖动的已知问题

生产模式

Webpack 仅在使用 --mode=production 标志时执行树状抖动。这将启用 UglifyJsPlugin,该插件将执行优化。为了深入了解一下;此插件实际上正在执行“死代码消除”,这是一个比规范的树状抖动更慢的过程,但结果类似。

Rollup 默认情况下启用树状抖动,但它仅与 ES 模块一起使用。Font Awesome 在其所有 NPM 包中提供 ES 模块,因此您应该可以正常使用。

使用 Webpack 4、uglify-es@3 和 uglify-js@3 的构建时间缓慢

您可能会遇到使用 Webpack 4、uglify-es@3 和 uglify-js@3 时构建时间出奇地慢的情况。例如,在使用 Webpack 4 运行生产构建时,它似乎会长时间挂起,状态为:92% chunk asset optimizationangular-cli 6.0 在幕后使用 Webpack 4,vue-cli 3.0 也是如此,也许还有其他类似的零配置开发框架工具。

以下是一些背景信息uglify-es 是一个基于 uglify-js 的缩小器。缩小器可以消除未使用的代码,这就是 Webpack 实现树状抖动的方式。它将死代码消除委托给用于生产捆绑包的缩小器。不幸的是,截至[email protected][email protected],此缩小器代码库中存在重大性能问题,恰好影响了像我们的图标包一样格式化的模块。此外,uglify-es 项目已转让所有权并更名为 terser

我们预计 Webpack 的未来版本将依赖于 terser 而不是 uglify-es,并将包含性能修复,这将在 Webpack 4 中再次使树状抖动变快。在此期间,如果您遇到此问题,您可以考虑一些解决方法。

解决方法 1:使用深度导入 - 每个图标都作为 CommonJS 格式的子模块提供,可以像以下示例一样导入。这完全避免了树状抖动。

// Bullet-proof deep import example
import { faCoffee } from '@fortawesome/free-solid-svg-icons/faCoffee' // <-- note the extra faCoffee there

解决方法 2:切换到 Babel Minify - 配置 webpack 以使用 babel-minify 而不是 uglify-esuglifyjs,如下所示

webpack.config.js
const BabelMinifyPlugin = require('babel-minify-webpack-plugin')
module.exports = {
// ...
optimization: {
minimizer: [
new BabelMinifyPlugin()
]
}
}

解决方法 3:禁用 collapse_vars - 坚持使用 uglify-esuglify-js 3.x,但配置 webpack 以禁用 collapse_vars 压缩选项。当然,这会影响您的整个构建,而不仅仅是 Font Awesome 模块。

webpack.config.js
// Disable collpase_vars
const UglifyWebpackPlugin = require('uglifyjs-webpack-plugin')
module.exports = {
// ...
optimization: {
minimizer: [
new UglifyWebpackPlugin({
uglifyOptions: {
compress: {
collapse_vars: false
}
}
})
]
}
}

零配置工具

如果您使用的是像 angular-cli 这样的工具,该工具在幕后使用 Webpack 4,则可能需要从工具的配置管理中弹出,如果您想进行上面建议的任何 Webpack 配置修改。

如果弹出太不可取,那么您最好的选择可能是降级到使用 Webpack 3 的该工具集的版本,直到此性能回归的修复可用,或者切换到使用深度导入(如上所述),直到修复可用。