logo
Laucher

Laucher

Laucher

2023年 03月 24日

0

使用 PurgeCSS 删除未使用的 CSS 代码

本文介绍了如何使用 PurgeCSS 工具来删除未使用的 CSS 代码,从而减小网站文件大小,提高性能优化。文章还涵盖了 PurgeCSS 在不同 JavaScript 库和框架中的使用示例,以及一些高级配置选项。无论您使用哪种 CSS 框架,本文都将帮助您优化您的项目并提高性能。

封面图

使用 PurgeCSS 删除未使用的 CSS 代码

删除不必要的代码将使您的网站加载速度更快,因为浏览器将请求和解析更少的代码。在本教程中,我们将探讨 PurgeCSS,这是一种用于删除未使用的 CSS 代码的工具。通过将 PurgeCSS 纳入我们的开发工作流程,我们可以轻松删除未使用的 CSS,从而减小 CSS 文件的体积,提高应用程序的整体性能。

未使用的 CSS 的问题

当使用像 Tailwind CSS 和 Bootstrap 这样的 CSS 框架时,我们经常会发现项目中存在未使用的 CSS 代码。这可能会导致性能问题,例如应用程序加载时间变长。

例如,Tailwind 使用 PurgeCSS 自动从最终构建中删除未使用的 CSS。Netflix Top 10 在整个网站上使用 Tailwind,只需要 6.5kB 的 CSS 文件。如果不删除未使用的 CSS,则 CSS 文件大小将是最终构建大小的十倍。

这是因为在开发过程中,您会使用类或声明,最终可能并未使用它们。这并不是开发者的错误,这种情况是难免的。因此,为了尝试您心中的设计,生成了越来越多的类(例如 Tailwind 中的类),您的 CSS 文件就会变得越来越大。

什么是 PurgeCSS?

PurgeCSS 是一种用于删除未使用的 CSS 的工具。它在优化应用程序以用于生产环境时非常有用。当您使用 CSS 框架,如 Bulma、Bootstrap 或 Tailwind 时,您会发现有很多未使用的 CSS。虽然这在开发过程中很好,但对于生产环境来说可能会导致性能问题。

这就是 PurgeCSS 发挥作用的地方。它分析您的内容以及您的 CSS 文件,以确定哪些样式未使用,并立即将其删除。PurgeCSS 与最常见的 JavaScript 库/框架一起工作,例如 Vue.js、React、Gatsby 等。

为什么要使用 PurgeCSS?

虽然 PurgeCSS 不是唯一用于删除未使用 CSS 的工具,但它因其模块化、易用性和丰富的自定义选项而脱颖而出。模块化使开发人员能够为特定用例和框架创建模块提取器。提取器是读取文件内容并提取所使用的 CSS 选择器列表的函数。

PurgeCSS 提供了一个非常可靠的默认提取器,可以处理各种文件类型。但是,默认情况下,PurgeCSS 忽略包含特殊字符(如@、: 和/)的未使用 CSS 代码。因此,PurgeCSS 可能不适用于您正在使用的确切文件类型或 CSS 框架。

此外,PurgeCSS 具有广泛的选项,允许您根据需要自定义其行为。例如,PurgeCSS 包括用于 fontFace、keyframes、提取器、css 等的选项。自定义可以提高 PurgeCSS 的性能和效率。

最后,PurgeCSS 非常易于入门,并包含详尽的文档。在撰写本文时,PurgeCSS 受到开发者的喜爱,每周在 npm 上有 90 万次以上的下载量和 7.4k 个 GitHub 星标。

PurgeCSS 如何工作?

PurgeCSS 最适用于生产构建,它会分析您的内容和 CSS,并删除未使用的样式。内容指示使用您的样式的页面。在开发过程中运行 PurgeCSS 可能是不必要的。这是因为在开发过程中,您经常会创建未使用的样式,这意味着您必须每次运行 PurgeCSS。

相反,您可以仅对生产构建运行它。这样,您就不必重新创建已删除的样式。因此,当您的应用程序准备好投入生产时,可以运行 PurgeCSS 一次。在我们深入使用 PurgeCSS 与流行的库/框架之前,让我们看一下它如何与原生 JavaScript 一起使用。请查看以下代码:

(async () => {
  const purgecss = await new PurgeCSS().purge({
    content: ['index.html'],
    css: ['style.css'],
  });

  console.log(purgecss);
})();

上面的代码是使用 PurgeCSS 的简单示例。我们指定了 index.html 作为内容之一,style.css 作为 CSS 之一。我们可以拥有更多的内容和 CSS 文件;有趣的是,内容不仅限于 HTML 文件(稍后我们将会看到更多)。上面的示例返回经过清除的样式数组。

除了内容和 css,还有更多的选项可用于指定您希望它执行的操作以及您希望它如何执行操作;我们稍后将看到更多。上面的示例可以用于任何原生 JavaScript 项目。要使用它,您需要有一个单独的 JavaScript 文件,只需运行一次即可删除未使用的样式。

因此,如果您的应用程序已准备好构建和部署,请创建新的 js 文件,粘贴代码并运行它。现在,我们只是记录 purgecss,但您可以更改它。并且,而不是记录结果,您可以将经过清除的样式替换为当前样式:

const { PurgeCSS } = require('purgecss');
const fs = require('fs');

(async () => {
  const purgecss = await new PurgeCSS().purge({
    content: ['index.html'],
    css: ['style.css'],
  });

  fs.writeFileSync('style.css', purgecss[0].css);
})();

正如您所看到的,使用 JavaScript 框架/库更轻松地替换已清除的样式。

使用 PurgeCSS 与 JavaScript 库/框架

PurgeCSS 与流行的 JavaScript 库/框架(如 React、Vue、Gatsby、Next.js、Nuxt.js 等)兼容。但是,在本教程中,我们将只介绍如何在 React 和 Vue 中使用 PurgeCSS。

PurgeCSS 与 React

首先,打开终端并运行以下命令,使用 Create React App 安装 React:

npx create-react-app purgecss-react-tutorial

接下来,进入我们刚刚创建的 purgecss-react-tutorial 目录:

cd purgecss-react-tutorial

现在,继续安装 PurgeCSS 及其依赖项:

npm i --save-dev @fullhuman/postcss-purgecss

打开您的 App.js 文件,并粘贴以下代码:

import "./App.css";

function App() {
  return <div className="App"></div>;
}

export default App;

在上面的代码中,我们创建了一个名为 App 的函数组件,返回了一个带有类名 “App” 的 div。我们的 App.css 保持不变,因此包含以下未使用的 CSS 代码:

.App {
  text-align: center;
}

.App-logo {
  height: 40vmin;
  pointer-events: none;
}

@media (prefers-reduced-motion: no-preference) {
  .App-logo {
    animation: App-logo-spin infinite 20s linear;
  }
}

.App-header {
  background-color: #282c34;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  font-size: calc(10px + 2vmin);
  color: white;
}

.App-link {
  color: #61dafb;
}

@keyframes App-logo-spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

打开 package.json 文件,然后在 scripts 下添加以下行:

"postbuild": "purgecss --css build/static/css/*.css --content build/index.html build/static/js/*.js --output build/static/css"

“post” 是可以添加到任何 npm 脚本的前缀,将在运行主要脚本时自动运行。在我们的情况下,postbuild 在执行 build 脚本后运行。由 postbuild 执行的命令包含三个选项。—css 选项指定 PurgeCSS 应该处理哪些 CSS 文件。 它可以是文件名或通配符的数组。—content 选项类似于 —css 选项,指定了 PurgeCSS 应该分析哪些内容。—output 选项指定应该将纯净的 CSS 文件写入的目录。默认情况下,它会将结果放在控制台中。

实际上,postbuild 执行的命令执行以下操作:

  • 检查 build/static/css 中的每个 CSS 文件
  • 匹配您的文件中使用的选择器,并删除任何未使用的 CSS
  • 将新的 CSS 文件输出到 build/static/css

现在,您只需运行 npm run build 来运行 React 应用程序的构建。要确认是否成功,请打开 build/static/css 中的 CSS 文件。输出看起来像下面的代码,只包含已使用的 CSS:

body {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
    Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
  margin: 0;
}
code {
  font-family: source-code-pro, Menlo, Monaco, Consolas, Courier New, monospace;
}
.App {
  text-align: center;
}
@-webkit-keyframes App-logo-spin {
  0% {
    -webkit-transform: rotate(0deg);
    transform: rotate(0deg);
  }
  to {
    -webkit-transform: rotate(1turn);
    transform: rotate(1turn);
  }
}
@keyframes App-logo-spin {
  0% {
    -webkit-transform: rotate(0deg);
    transform: rotate(0deg);
  }
  to {
    -webkit-transform: rotate(1turn);
    transform: rotate(1turn);
  }
}

PurgeCSS 与 Vue.js

同样,您需要打开终端窗口,并运行以下命令来创建一个新的 Vue 项目。首先确保已安装 Vue CLI:

npm install -g @vue/cli

现在,运行以下命令来创建一个 Vue 项目:

vue create purgecss-vue-tutorial

然后,进入 purgecss-vue-tutorial,并添加 PurgeCSS:

cd purgecss-vue-tutorial

vue add @fullhuman/purgecss

这将生成一个 postcss.config.js 文件,其中包含已经设置好以适应您的 Vue 应用程序的 PurgeCSS 配置。您始终可以更改这些配置以最好地满足您的需求。我们将在本文的后面部分看到如何进行这些更改。

但是,对于本教程,我们无需更新配置。默认配置足以在此项目中运行 PurgeCSS。现在,让我们更新应用程序的一些内容,以查看 PurgeCSS 在 Vue 中的工作情况。前往 HelloWorld.vue,并用以下代码替换其中的代码:

<template>
  <a href="#">Hello world</a>
</template>
<script>
export default {
  name: 'HelloWorld',
  props: {
    msg: String,
  },
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
  margin: 40px 0 0;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
span {
  color: red;
}
</style>

我们减少了内容并添加了一些未使用的样式(仅用于演示)。现在,让我们构建我们的应用程序,以查看我们的应用程序的最终构建中的 CSS。在终端中运行 npm run build,并等待构建完成。要确认,请打开 dist/css 中的 CSS 文件,您将找到只包含已使用样式的 CSS 输出:

a[data-v-70cf4e96] {
  color: #42b983;
}

#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}

高级配置选项

到目前为止,我们只看到了三个配置选项:content、css 和 outline,但更多配置选项可让您自定义 PurgeCSS。

关键帧和字体

在 PurgeCSS v2.0 之前,未使用的字体和关键帧代码默认会被删除。但是,当错误使用这些功能时,代码会中断。默认情况下,未使用的字体和关键帧代码现在不会被触碰。您可以通过将 keyframes 和 fontfaces 选项设置为 true 来更改此默认行为:

(async () => {
  const purgecss = await new PurgeCSS().purge({
    content: ['index.html'],
    css: ['style.css'],
    keyframes: true,
    fontFaces: true,
  });

  console.log(purgecss);
})();

配置选项也可以在 purgecss.config.js 这样的配置文件中使用:

// purgecss.config.js
module.exports = {
  content: ['index.html'],
  css: ['style.css'],
  keyframes: true,
  fontFaces: true,
}


(async () => {
  const purgecss = await new PurgeCSS().purge('./purgecss.config.js');
  console.log(purgecss);
})();

原始内容和 CSS 值

您可以直接传递内容和 CSS 的值,而无需将文件链接到它,就像我们一直在做的那样。以下是示例:

// purgecss.config.js
module.exports = {
  content: [
    {
      raw: '<html><body><p>Hello world</p></body></html>',
      extension: 'html',
    },
  ],
  css: [
    {
      raw: 'p { color: red }',
    },
  ],
};

提取器

在极少数情况下,PurgeCSS 可能无法删除未使用的 CSS 或删除已使用的 CSS。在这种情况下,您必须使用自定义提取器。PurgeCSS 依赖于提取器来获取文件中使用的选择器列表。

有些软件包提供了特定扩展名的提取器。例如,purgecss-from-js 适用于 .js 扩展名。对于扩展名,使用特定提取器应该提供最佳准确性:

// purgecss.config.js
import purgeJs from 'purgecss-from-js'
import purgeHtml from 'purgecss-from-html'

const options = {
  content: ['index.html'],
  css: ['style.css'],
  extractors: [
    {
      extractor: purgeJs,
      extensions: ['js']
    },
    {
      extractor: purgeHtml,
      extensions: ['html']
    }
  ]
}
export default options

变量

默认情况下,不会删除未使用的 CSS 变量。如果要删除它们,您必须在您的 purgecss.config.js 文件中将 variables 设置为 true:

module.exports = {
    content: ['index.html'],
    css: ['style.css'],
    variables: true,
}

安全列表和注释

您可以指示哪些选择器可以留在最终的 CSS 中。我们可以通过 PurgeCSS 选项 safelist 或特殊的 CSS 特殊注释来实现。使用 safelist:

module.exports = {
    content: ['index.html'],
    css: ['style.css'],
    safelist: ['random', 'button'],
}

在这种情况下,.random、#random、button、.button 和 #button 将全部被 PurgeCSS 忽略,不会被删除。您可以使用正则表达式将其提升到下一个级别:

module.exports = {
    content: ['index.html'],
    css: ['style.css'],
    safelist: [/red$/, /^bg/],
}

在这种情况下,任何以 red 结尾(例如,bg-red、btn-red)或以 bg 开头(例如,bg-blue、bg-red)的选择器都不会被删除。默认情况下,PurgeCSS 不会删除注释。只有旨在自定义 PurgeCSS 行为的特殊注释才会被删除。

一个常见的特殊注释集是用于指定哪些选择器可以保留在最终 CSS 中的注释:

/* purgecss start ignore */
h1 {
  color: pink;
  font-size: 2rem;
}
/* purgecss end ignore */

结论

在本文中,我们探讨了 PurgeCSS,这是一个用于删除代码中未使用的 CSS 的工具,从而减小文件大小并提高优化。我们介绍了 PurgeCSS 的主要功能,包括其模块化、自定义选项和易用性。

然后,我们回顾了如何在 React 和 Vue 中开始使用 PurgeCSS,以及一些配置选项,以帮助自定义 PurgeCSS 以满足我们的需求。

即使您决定使用像 Tailwind、Bootstrap、MaterializeCSS 或 Foundation 等 CSS 框架,PurgeCSS 也应该可以完美工作。希望您喜欢本文!如果您还有其他问题或需要进一步的帮助,请随时提问。

评论