去除未使用的样式

Bootstrap 这样的框架往往带有很多 CSS。通常你只使用它的一小部分,但打包时却包含了未使用的那一大部分,这不是一个符合预期的结果。

PurifyCSS 是一个可以通过分析文件来实现这一目标的工具。它遍历您的代码并确定正在使用的 CSS 类,通常这就可以收集到足够的信息来从项目中删除未使用的 CSS。它也适用于单页应用程序。

uncssPurifyCSS 的一个很好的替代品。它通过 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”看起来应该像一个按钮。

Hello-world-like-a-button-pure-css,demo-of-eliminating-unused-css

打包应用(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-criticalhtml-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 特性。

用户头像
登录后发表评论