Tailwind CSS 生產(chǎn)優(yōu)化

2022-07-26 09:35 更新

生產(chǎn)優(yōu)化

從您的生產(chǎn)構(gòu)建中移除未使用的 CSS,以獲得最佳性能。


使用默認(rèn)配置,TailwindCSS 的開發(fā)版本是3645.2kB未壓縮,294.2kB用Gzip進(jìn)行壓縮,72.8kB用Brotli進(jìn)行壓縮。

Uncompressed Minified Gzip Brotli
3645.2kB 2936.0kB 294.2kB 72.8kB

這聽起來可能很龐大,那是因?yàn)樵O(shè)計(jì)就很龐大。

為了使開發(fā)經(jīng)驗(yàn)盡可能的富有成效,Tailwind 為您生成了成千上萬的功能類,其中大部分您可能不會真正使用。

把 Tailwind 想象成一個(gè)巨大的樂高盒子—您把它傾倒在地板上,建造您想建造的東西,然后當(dāng)您完成后,您把所有您不用的碎片放回盒子里。

例如,Tailwind 為您的間距尺度中的每一個(gè)尺寸,為您可能想要應(yīng)用邊距的元素的每一個(gè)側(cè)面,在您的項(xiàng)目中使用的每一個(gè)斷點(diǎn)生成邊距實(shí)用程序。這導(dǎo)致了數(shù)以百計(jì)的不同組合,這些組合都是重要的,但不可能都是需要的。

當(dāng)構(gòu)建生產(chǎn)時(shí),您應(yīng)該總是使用 Tailwind 的 ?purge ?選項(xiàng)來 tree-shake 優(yōu)化未使用的樣式,并優(yōu)化您的最終構(gòu)建大小當(dāng)使用 Tailwind 刪除未使用的樣式時(shí),很難最終得到超過 10kb 的壓縮 CSS。

編寫可清除的 HTML

在開始使用 ?Purge ?功能之前,重要的是要了解它是如何工作的,并建立正確的心理模型,以確保您在為生產(chǎn)構(gòu)建時(shí)永遠(yuǎn)不會意外地刪除重要的樣式。

PurgeCSS(我們在引擎下使用的庫)在尋找 HTML 中的類的方式上故意非常幼稚。它并不試圖解析您的 HTML 并查找類的屬性,也不動(dòng)態(tài)執(zhí)行您的 JavaScript —它只是在整個(gè)文件中查找符合這個(gè)正則表達(dá)式的任何字符串。

  /[^<>"'`\s]*[^<>"'`\s:]/g

這基本上可以匹配任何由空格、引號或角括號分隔的字符串,包括 HTML 標(biāo)簽、屬性、類,甚至是您標(biāo)記中的實(shí)際書面內(nèi)容。

<div class="md:flex">
  <div class="md:flex-shrink-0">
    <img class="rounded-lg md:w-56" src="/img/shopping.jpg" alt="Woman paying for a purchase">
  </div>
  <div class="mt-4 md:mt-0 md:ml-6">
    <div class="uppercase tracking-wide text-sm text-indigo-600 font-bold">
      Marketing
    </div>
    <a href="/get-started" class="block mt-1 text-lg leading-tight font-semibold text-gray-900 hover:underline">
      Finding customers for your new business
    </a>
    <p class="mt-2 text-gray-600">
      Getting a new business off the ground is a lot of hard work.
      Here are five ideas you can use to find your first customers.
    </p>
  </div>
</div>

這意味著,重要的是避免在您的模板中使用字符串連接動(dòng)態(tài)創(chuàng)建類字符串,否則 PurgeCSS 將不知道保存這些類。

不要使用字符串連接來創(chuàng)建類名

<div class="text-{{  error  ?  'red'  :  'green'  }}-600"></div>

動(dòng)態(tài)選擇一個(gè)完整的類名

<div class="{{  error  ?  'text-red-600'  :  'text-green-600'  }}"></div>

只要一個(gè)類名出現(xiàn)在您的模板中,PurgeCSS 就不會刪除它。

刪除未使用的CSS

基本用途

要開始使用,請使用 ?purge ?選項(xiàng)為您所有的模板文件提供一個(gè)路徑數(shù)組。

// tailwind.config.js
module.exports = {
  purge: [
    './src/**/*.html',
    './src/**/*.vue',
    './src/**/*.jsx',
  ],
  theme: {},
  variants: {},
  plugins: [],
}

例如,如果您的項(xiàng)目中有一個(gè) JS 文件,在您的 HTML 中動(dòng)態(tài)切換一些類,您應(yīng)該確保在這個(gè)列表中包括該文件。

現(xiàn)在,每當(dāng)您在編譯 CSS 時(shí)將 ?NODE_ENV ?設(shè)置為 ?production?,Tailwind 將自動(dòng)從您的 CSS 中清除未使用的樣式。

手動(dòng)啟用

如果您想手動(dòng)控制是否應(yīng)該刪除未使用的樣式(而不是隱性地依賴環(huán)境變量),您可以使用一個(gè)對象語法,并提供 ?enabled ?選項(xiàng),使用 ?content ?選項(xiàng)指定您的模板。

// tailwind.config.js
module.exports = {
  purge: {
    enabled: true,
    content: ['./src/**/*.html'],
  },
  // ...
}

我們建議只在生產(chǎn)中移除未使用的樣式,因?yàn)樵陂_發(fā)中移除它們意味著您需要在任何時(shí)候改變您的模板時(shí)重新編譯,并且在啟用 PurgeCSS 的情況下編譯速度要慢得多。

將特定類列入安全列表

如果您需要將特定類列入安全列表以確保它們不會被意外從 CSS 中刪除(可能是因?yàn)樗鼈冇糜趤碜詳?shù)據(jù)庫或類似內(nèi)容的內(nèi)容中),您可以使用我們的頂級 ?safelist? 選項(xiàng):

// tailwind.config.js
module.exports = {
  purge: {
    content: ['./src/**/*.html'],
    safelist: [
      'bg-blue-500',
      'text-center',
      'hover:opacity-100',
      // ...
      'lg:text-right',
    ]
  },
  // ...
}

轉(zhuǎn)換內(nèi)容

有時(shí)您正在以一種可編譯為 HTML 的格式創(chuàng)作內(nèi)容,最好先將該內(nèi)容編譯為 HTML,然后再尋找潛在的類。一個(gè)很好的例子是使用 markdown 文件。

您可以使用 ?transform ?選項(xiàng)告訴 Tailwind 在查找類之前轉(zhuǎn)換與特定擴(kuò)展名匹配的任何文件以保證最準(zhǔn)確的結(jié)果:

// tailwind.config.js
let remark = require('remark')

module.exports = {
  purge: {
    content: ['./src/**/*.{html,md}'],
    transform: {
      md: (content) => {
        return remark().process(content)
      }
    }
  },
  // ...
}

自定義提取邏輯

如果您需要覆蓋 Tailwind 用于檢測特定文件類型內(nèi)容中的類的邏輯,您可以使用 ?extract ?選項(xiàng)提供一個(gè)函數(shù),該函數(shù)將用于檢測匹配文件中的潛在類:

// tailwind.config.js
module.exports = {
  purge: {
    content: ['./src/**/*.{html,md}'],
    extract: {
      md: (content) => {
        return content.match(/[^<>"'`\s]*/)
      }
    }
  },
  // ...
}

這是一項(xiàng)高級功能,大多數(shù)用戶不需要它。 Tailwind 中的默認(rèn)提取邏輯適用于幾乎所有項(xiàng)目。

保留 HTML 元素

默認(rèn)情況下,Tailwind 將保留所有基本的 HTML 元素樣式在您的 CSS 中,如 ?html?,?body?,?p?,?h1 ?等標(biāo)簽的樣式。這是為了減少意外的過度清洗,例如在您使用 markdown 源文件的情況下(其中沒有實(shí)際的 ?h1 ?標(biāo)簽),或者使用一個(gè)框架將文檔外殼(包含 ?html ?和 ?body ?標(biāo)簽)隱藏在供應(yīng)商目錄的某個(gè)地方(像 Next.js 那樣)。

如果您想禁止這種行為,您可以將 ?preserveHtmlElements ?設(shè)置為 false。

// tailwind.config.js
module.exports = {
  purge: {
    preserveHtmlElements: false,
    content: ['./src/**/*.html'],
  },
  // ...
}

清理特定層

默認(rèn)情況下,Tailwind 將清除 ?base ?、?components ?和 ?utilities ?層中的所有樣式。如果您想更改此設(shè)置,請使用 ?layers? 選項(xiàng)手動(dòng)指定您要清除的圖層:

// tailwind.config.js
module.exports = {
  purge: {
    layers: ['components', 'utilities'],
    content: ['./src/**/*.html'],
  },
  // ...
}

移除所有未使用到的 styles

默認(rèn)情況下,Tailwind 將只刪除它自己生成的未使用的類,或者被明確地包裹在 ?@layer? 指令中。它不會從第三方 CSS 中移除未使用的樣式,比如您拉到您的項(xiàng)目中的 datepicker 庫。

/* These styles will all be purged */
@tailwind base;
@tailwind components;
@tailwind utilities;

/* These styles will be purged */
@layer components {
  .btn { /* ... */ }
}

/* These styles will not be purged */
.flatpickr-innerContainer { /* ... */ }
.flatpickr-weekdayContainer { /* ... */ }
.flatpickr-weekday { /* ... */ }

這是為了避免意外地刪除那些您可能需要的但在模板中沒有直接引用的樣式,比如那些只在 ?node_modules ?文件夾深處引用的類,它們是其他依賴關(guān)系的一部分。

如果您真的想刪除所有未使用的樣式,設(shè)置 ?mode: 'all'? 和 ?preserveHtmlElements: false?,并且要非常小心地提供可能引用任何類或HTML元素的所有文件的路徑。

// tailwind.config.js
module.exports = {
  purge: {
    mode: 'all',
    preserveHtmlElements: false,
    content: [
      './src/**/*.js',
      './node_modules/flatpickr/**/*.js',
    ],
  },
  // ...
}

我們不推薦這樣做,一般來說,您會發(fā)現(xiàn)堅(jiān)持使用更保守的默認(rèn)方法可以獲得 99% 的文件大小的好處。

刪除未使用的 keyframes

默認(rèn)情況下,PurgeCSS 不會刪除未使用的 ?@keyframes? 規(guī)則,因此即使您沒有使用它們,您也可能會注意到樣式表中遺留了一些與動(dòng)畫相關(guān)的樣式。您可以使用 ?options ?下的 PurgeCSS 的 ?keyframes ?選項(xiàng)刪除這些:

// tailwind.config.js
module.exports = {
  purge: {
    content: ['./src/**/*.html'],
    options: {
      keyframes: true,
    },
  },
  // ...
}

PurgeCSS選項(xiàng)

如果你需要直接向PurgeCSS傳遞任何其他選項(xiàng),你可以使用?options?來實(shí)現(xiàn)。

// tailwind.config.js
module.exports = {
  purge: {
    content: ['./src/**/*.html'],

    // These options are passed through directly to PurgeCSS
    options: {
      safelist: ['bg-red-500', 'px-4'],
      blocklist: [/^debug-/],
      keyframes: true,
      fontFace: true,
    },
  },
  // ...
}

可用的選項(xiàng)列表可以在 PurgeCSS 文檔中找到。

其他辦法

如果您因?yàn)槟撤N原因不能使用 PurgeCSS,您也可以通過從您的配置文件中刪除未使用的值來減少Tailwind的足跡。

默認(rèn)的主題提供了一套非??犊念伾?,斷點(diǎn),大小,邊距等,以確保當(dāng)您把Tailwind拉下來做原型,創(chuàng)建一個(gè) CodePen 演示,或者只是嘗試一下工作流程,體驗(yàn)是盡可能的愉快和流暢。

我們不希望您不得不去寫新的 CSS,因?yàn)槲覀儧]有提供足夠的 padding helpers,或者因?yàn)槟霝槟难菔臼褂贸壬桨?,而我們只給您藍(lán)色。

不過這也是有代價(jià)的:默認(rèn)的構(gòu)建要比在一個(gè)有專門配置文件的項(xiàng)目上要重得多。

以下是一些策略,您可以用它來保持您生成的 CSS 小而性能好。

限制您的調(diào)色板

默認(rèn)的主題包含了高達(dá) 84 種顏色,用于背景、邊框、文本和占位符,所有這些顏色都有 ?hover:? 和 ?focus:? 變體,以及六種默認(rèn)屏幕尺寸的響應(yīng)變體。

默認(rèn)情況下,有成千上萬的類生成以適應(yīng)這些顏色,它占了最終構(gòu)建大小的近一半。

很少有項(xiàng)目真正需要這么多顏色,刪除不需要的顏色會對整體文件大小產(chǎn)生巨大影響。

以下是使用較小的調(diào)色板對最終大小的影響。

Colors Original Minified Gzip Brotli
84 (default) 3645.2kB 2936.0kB 294.2kB 72.8kB
50 2805.8kB 2231.3kB 238.7kB 59.3kB
25 2177.6kB 1702.8kB 198.3kB 50.6kB

刪除未使用的斷點(diǎn)

由于幾乎每個(gè) Tailwind 功能類都是為每一個(gè)屏幕尺寸復(fù)制的,所以使用較少的屏幕尺寸也會對整體文件大小產(chǎn)生巨大的影響。

以下是定義較少屏幕如何影響輸出:

Breakpoints Original Minified Gzip Brotli
(default) 3645.2kB 2936.0kB 294.2kB 72.8kB
3 2395.9kB 1936.0kB 196.2kB 62.3kB
2 1781.4kB 1446.0kB 147.4kB 57.3kB
1 1167.3kB 956.3kB 98.6kB 52.5kB

如果您只需要 3 種屏幕尺寸和 35 種顏色,那么您可以在不更改任何其他內(nèi)容的情況下將其壓縮為 46.8kB 。

禁用未使用到的核心插件和變體

如果您不希望在您的項(xiàng)目中需要某個(gè)功能插件,您可以通過在配置文件的 ?corePlugins ?部分將其設(shè)置為 ?false ?來完全禁用它。

// tailwind.config.js
module.exports = {
  // ...
  corePlugins: {
    float: false
  }
}

如果您只需要少量的功能類,您可以向 ?corePlugins ?傳遞一個(gè)數(shù)組,其中包含您想保留的功能插件。

// tailwind.config.js
module.exports = {
  // ...
  corePlugins: [
    'margin',
    'padding'
  ]
}

以上將禁用除 margin 和 padding 以外的所有功能類。

如果需要一個(gè)功能類,但不需要響應(yīng)式版本,將其變體設(shè)置為空數(shù)組,以減少 83% 的類生成。

module.exports = {
  // ...
  variants: {
    appearance: []
  }
}

與限制您的調(diào)色板或使用較少的斷點(diǎn)相比,這些大多是小的優(yōu)化,但它們?nèi)匀豢梢赃M(jìn)一步減小構(gòu)建體積。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號