像 Bootstrap 这样的框架往往带有很多 CSS。通常你只使用它的一小部分,但打包时却包含了未使用的那一大部分,这不是一个符合预期的结果。
PurifyCSS 是一个可以通过分析文件来实现这一目标的工具。它遍历您的代码并确定正在使用的 CSS 类,通常这就可以收集到足够的信息来从项目中删除未使用的 CSS。它也适用于单页应用程序。
uncss 是 PurifyCSS 的一个很好的替代品。它通过 PhantomJS 运行,并以不同的方式执行其工作。您可以使用 uncss 本身作为 PostCSS 插件。
如果使用 CSS Modules,则需要小心。您必须按照 purifycss-webpack readme 文件中所讨论的那样将相关类列入白名单。
设置 Pure.css
为了使演示更加真实,我们安装一下 Pure.css——一个小的 CSS 框架,并从项目中引用它,以便您可以看到 PurifyCSS 的运行情况。尽管它们命名有相似之处,但这两个项目没有任何关联。
npm install purecss --save
为了在项目中使用 Pure.css,我们通过 import
导入它:
src/index.js
import "purecss";
...
import
语句之所以有用,是因为 Webpack 会去查看 Pure.css 中的 package.json 文件,并根据"browser": "build/pure-min.css"
字段找到相应的资源,详情请参阅 resolve.mainFields。
接下来,我们在演示组件使用 Pure.css 类:
SRC / component.js
export default (text = "Hello world") => {
const element = document.createElement("div");
element.className = "pure-button";
element.innerHTML = text;
return element;
};
启动应用(npm start
),“Hello world”看起来应该像一个按钮。
打包应用(npm run build
)应该可以看到以下输出:
Hash: 36bff4e71a3f746d46fa
Version: webpack 4.1.1
Time: 739ms
Built at: 3/16/2018 4:26:49 PM
Asset Size Chunks Chunk Names
main.js 747 bytes 0 [emitted] main
main.css 16.1 KiB 0 [emitted] main
index.html 220 bytes [emitted]
...
正如您所看到的,CSS 文件的大小增加了,这可以通过 PurifyCSS 来解决。
启用 PurifyCSS
使用 PurifyCSS 可以节省大量成本。在示例项目中,他们通过压缩抽取 Bootstrap(140 kB)使用到的部分,将最终的体积变为 35 kB,仅为原来的 40%。效果不言而喻。
purifycss-webpack 可以实现类似的效果。您应该使用 MiniCssExtractPlugin
来配合它从而获得最佳效果。首先,我们安装一下它和 glob :
npm install glob purifycss-webpack purify-css --save-dev
您还需要将 PurifyCSS 配置如下:
webpack.parts.js
const PurifyCSSPlugin = require("purifycss-webpack");
exports.purifyCSS = ({ paths }) => ({
plugins: [new PurifyCSSPlugin({ paths })],
});
接下来,我们将该部分配置与主配置合并。另外,这个插件 应当在 MiniCssExtractPlugin
之后使用; 否则,它不起作用:
webpack.config.js
...
const path = require("path");
const glob = require("glob");
const parts = require("./webpack.parts");
const PATHS = {
app: path.join(__dirname, "src"),
};
...
const productionConfig = merge([
...
parts.purifyCSS({
paths: glob.sync(`${PATHS.app}/**/*.js`, { nodir: true }),
}),
]);
顺序非常重要。CSS 的抽取必须要在 purify 之前。
如果你现在运行 npm run build
,你应该看到一些东西:
Hash: 36bff4e71a3f746d46fa
Version: webpack 4.1.1
Time: 695ms
Built at: 3/16/2018 4:29:54 PM
Asset Size Chunks Chunk Names
main.js 747 bytes 0 [emitted] main
main.css 2.07 KiB 0 [emitted] main
index.html 220 bytes [emitted]
...
样式的的大小明显减少。之前为 16k,现在大约有 2k。对于更大体积的 CSS 框架而言,差异将更加明显。
PurifyCSS 支持包括 minify
的其他选项,您可以在实例化插件时通过 purifyOptions
字段启用它们。鉴于 PurifyCSS 无法鉴别出所有你想要使用的类,您可以使用 purifyOptions.whitelist
数组来定义选择器,无论如何它都应该留在结果中。
使用 PurifyCSS 会丢失 CSS 源映射,即使您已在特定的 loader 中配置启用它们,因为 PurifyCSS 是在它们之后工作的。
关键路径渲染
关键路径渲染的概念从不同角度看待 CSS 性能。它不是优化大小,而是优化渲染顺序,并强调首屏CSS。实现思路是通过渲染页面来确定展示结果时所需要的 CSS 规则。
webpack-critical 和 html-critical-webpack-plugin 将该技术作为 HtmlWebpackPlugin
插件的形式实现了出来。isomorphic-style-loader 使用 Webpack 和 React 实现了相同的功能。
Addy Osmani 的 critical-path-css-tools 列出了其他相关工具。
总结
使用 PurifyCSS 可以显著减小文件大小。它主要用于依赖大量 CSS 框架的静态站点,站点或应用程序变得越动态,就越难以可靠地进行分析所要的 CSS。
回顾一下:
- 使用 PurifyCSS 可以去除未使用的 CSS,它对源代码执行静态分析。
- 可以通过 purifycss-webpack 启用该功能,并且它应该
MiniCssExtractPlugin
插件之后。 - 最好的情况是,PurifyCSS 可以去除大多数(如果不是全部)未使用的 CSS 规则。
- 关键路径渲染是另一种 CSS 技术,它强调首先渲染首屏 CSS。他们的想法是尽可能快地呈现内容,而不是等待加载所有 CSS。
在下一章中,您将学习autoprefix。启用该功能可以更方便地开发适用于旧版浏览器的高级 CSS 特性。