CSSミニファイア
コメントとスペースを削除し、値を最適化してCSSを圧縮します。
CSSミニファイについて
Brotli がテキストストリームをそれほど積極的に圧縮するので、別のミニフィケーションパスの限界価値が崩壊したと仮定する誘惑があります。Sentry のエンジニアリングブログは2024年4月にちょうどその議論をして、逆を結論づけました:ミニフィケーションは依然として支払います。グローバル中央値モバイルインターネット速度は約 53 Mbps で Brotli が CDN エッジで普遍的に展開されている、「100 リソース合計でページロードあたり 1 KB 削減できれば、それらのユーザーのページ速度を 15 ms 改善できる」。任意の自明でないサイトの訪問者ベースで掛けると、それは実際の帯域幅請求書、モバイルデバイスでの実際のバッテリーコスト、Lighthouse レポートでの実際の位置変化になります。
メカニズムが重要です。Gzip と Brotli は繰り返されるバイトシーケンスを探し、各繰り返しをスライディングウィンドウ辞書への後方参照としてエンコードする汎用可逆コンプレッサーです。同じブラウザ動作を生成するが異なるバイトを含む 2 つの CSS ファイルは異なるサイズに圧縮されます。margin: 10px 10px 10px 10px; と margin:10px は意味的に同一ですが、最初のものは多くが繰り返されてもエンコードする文字が多く、Brotli は繰り返しを見つけるのが上手だが、構文的に異なる 2 つの CSS 文字列が同じルールを表現することを理解しません。CSS 認識ミニファイアだけがそれをできます。Cloudflare の学習ハブは典型的な生テキスト削減を 30-50 % に置きます、その上の Brotli はさらに控えめな 5-15 % を加えます、しかしゼロではなく、規模で加算されます。
CSS はレンダーをブロックする、それがバイトが重要な理由
Largest Contentful Paint は 3 つの Core Web Vitals の 1 つです、「Good」のしきい値はロードの 75 パーセンタイルで 2.5 秒です。Lighthouse の全体的なパフォーマンススコアは LCP に合計の 25 % の重みを置きます。CSS はデフォルトでレンダーをブロックします、ブラウザが <link rel="stylesheet"> を見ると、ファイルがダウンロードされ CSSOM が構築されるまでレンダーを一時停止します、後のスタイルシートのルールが前のルールをオーバーライドする可能性があり、ブラウザがアンスタイル化または誤ってスタイル化された状態でペイントするリスクを冒せないからです。CSS Object Model は DOM とは異なり、増分的に構築されません、パーサーはどのルールが勝つかを知るために完全なシートが必要です。JavaScript もそこでブロックされます:CSSOM が完了するまでスクリプトは安全に実行できません。実用的な意味は、レンダーをブロックする CSS のすべてのバイトはすべての Core Web Vital のクリティカルパス上にあるということです。100 KB のミニファイされたバンドルは非ミニファイの 150 KB と比較して高速 4G リンクで約 30 ms 節約します、ページごとに小さい、しかし Vodafone ケーススタディは 31 % の LCP 改善で売上の 8 % 増加を示しました。二次効果はさらに大きい:より速い LCP は Lighthouse スコアを上げ、それが Web Vitals がランキングシグナルであることが知られているサイトの Google 上での可視性を上げます。
CSS ミニファイアが実際に行うこと
- 空白の削除。 人間の読みやすさのためだけに存在するスペース、タブ、改行が削除されます。文字列内(font-family 名、content 値、URL)とトークンを分離する空白は残ります、
1px solid redは1pxsolidredになれません、パーサーが 3 つの値を認識しなくなるからです。 - コメントの削除。
/* ... */ブロックは削除されます。広く尊重されている慣習は、/*!で始まるコメントは重要として扱われ、通常著作権またはライセンス通知、cssnano、clean-css、lightningcss、esbuild のような本番ミニファイアによって保持されることです。 - ゼロユニットの削減。
0px、0em、0%、0pt、0vwはすべて0に削減されます、ゼロ長は単位に関係なく同じ長さだからです。注意深いエッジケース(Miriam Suzanne の「Not All Zeros are Equal」、2022):calc()、min()、max()、clamp()内、CSS カスタムプロパティ内のゼロは安全に単位を剥がせません、CSS Values and Units Module Level 4 の型付き算術ルールが長さと数値を区別するために単位を要求するからです。transitionの0sは0になれません、プロパティが時間値を要求するからです。 - 16 進カラーの短縮。 各桁ペアが同一である 6 桁の 16 進カラーは 3 桁で書ける:
#FFFFFF → #FFF、#336699 → #369。CSS Color 仕様は 3 桁形式を完全に同等として CSS1 以来定義しています。 - 末尾セミコロンの削除。 ルールブロックの最後の宣言と閉じ括弧の間のセミコロンはオプションです、
color:red;}はcolor:red}になります。ルールごとに 1 バイト、加算されます。 - キーワードの小文字化。 CSS キーワードは大文字小文字を区別しないので、
BLOCKとblockは同じことを意味しますが、小文字はより良く圧縮し、均一にトークン化します。 - ショートハンドへの削減。
margin: 10px 10px 10px 10pxはmargin: 10pxになります、margin: 10px 20px 10px 20pxはmargin: 10px 20pxになります。本番ミニファイアはmargin、padding、border、border-radius、background、font、transition、animation、grid ファミリーのショートハンドルールを知っています。
ミニファイア vs オプティマイザ、安全 vs 積極的なライン
cssnano のドキュメントは「default」プリセット(安全な変換のみ)と「advanced」プリセット(CSS の仮定に依存する積極的な変換)の間を区別します。デフォルトプリセットは考えずに有効にするものです、advanced プリセットは監査後に有効にするものです、いくつかの最適化は微妙なカスケード動作、ベンダープレフィックス、またはブラウザ固有の癖に依存するコードを壊す可能性があります。Advanced 変換は圧縮性を改善するためにシート内のルールを並べ替えるかもしれません、display: flex; display: grid; のような意図的な重複プロパティフォールバックがある場合はリスキーです。それらはカンマ区切りセレクタリストの同一のルール本体をマージできます。それらは上書きされる宣言をデッドコードとして削除でき、フォールバックについて同じ警告があります。それらは display 値、変換関数、カスタム識別子を正規化できます、translate3d(0,0,0) は GPU 昇格副作用に依存していなければ translate(0) に簡素化できます。それらは Browserslist ターゲットによって未使用のベンダープレフィックスを削除できます。csso(Yandex、2011)は純粋なミニファイアではなく「構造的オプティマイザ」と自分自身を説明します、3 つの変換カテゴリ:クリーンアップ、圧縮、再構造化。Lightning CSS は同じ分割を説明します:常に安全な「minify」パス、加えて現代の CSS を古いブラウザが理解するものにコンパイルする targets 認識変換のセット。正直なライン:ミニファイアは考えずにあらゆる CSS ファイルに適用できるもの、オプティマイザはコードベースの知識で適用するものです。
CSS ミニフィケーションツールの簡単な歴史
YUI Compressor(2007)。 Yahoo の Julien Lecomte は2007年8月11日に YUI Compressor を発表しました。元のバージョンは JavaScript のみを処理しました、3 日後、バージョン 2.0 は Isaac Schlueter が個人使用のために最初に書いた regex ベースの CSS ミニファイアを統合することで CSS サポートを追加しました。YUI Compressor は何年もの間事実上の標準でした、特に Java/Maven と Rails-asset-pipeline の世界で、依然として今日使用されています、YUI ライブラリ自体が2014年に Yahoo によって廃止されたとはいえ。YUI Compressor の CSS 側は AST ベースではなく常に regex ベースでした、その後の小さなブラウザ側ツールに響く設計決定です。
clean-css(2011)。 Jakub Pawlowicz は2011年に GitHub の GoalSmashers 組織の下で clean-css を公開しました、「Node.js と Web のための高速で効率的な CSS オプティマイザ」として位置付けました。それは Node.js エコシステムのために特別に設計された最初の主要な CSS ミニファイアで、Grunt と Gulp パイプラインのデフォルトになりました。現在の 5.x ラインは npm から週に約 2,100 万ダウンロードを引き付け、@import インライン化、URL リベース、ソースマップをサポートし、安全 vs 積極的な分割を明示する階層的「最適化レベル」モデルを持ちます。csso(2011) は Yandex の内部プロジェクトとして始まり、Vitaly Harisov のアイデアに基づく Sergey Kryzhanovsky の2011年著作権で公開されました。cssnano(2015年4月)、Ben Briggs によるもの、は異なるアプローチを取りました:単一のモノリシックミニファイアではなく、cssnano は小さな PostCSS プラグインのキュレーションされたバンドル(デフォルトプリセットで約 30)です。それはその構成可能性のおかげで、そして PostCSS 自体(Andrey Sitnik のフレームワーク、2013年11月に最初に公開)が他の多くのもの(Autoprefixer、Stylelint、Tailwind の処理パイプライン)の基板になったので、JavaScript エコシステムの支配的な CSS ミニファイアになりました。cssnano は現在バージョン 7.x で、webpack の css-minimizer-webpack-plugin、Next.js、その他多くのフレームワークデフォルトでデフォルトの CSS ミニファイアです。
esbuild の CSS ミニファイア(2020-2021)。 Figma の共同創業者 Evan Wallace は esbuild を「2019-2020年の冬休み中に書いた趣味プロジェクト」として公開しました。Go で書かれ、esbuild は当時の JavaScript ベースのバンドラーより 10-100× 高速でした。CSS サポートは2021年まで成熟しました、それは現在 Vite、tsup、無数のフレームワークテンプレートで基礎ミニファイアとしてどこにでもあります。Lightning CSS(2021/2022)。 Parcel の作成者 Devon Govett は2021年に Parcel CSS を発表しました、Rust でゼロから書かれた CSS パーサー、トランスフォーマー、バンドラー、ミニファイア。その主張は速度(既存の JS ベースツールより 10-100× 高速)、正確性(regex パターンマッチングではなく、CSS 仕様準拠の実際のパーサー)、ターゲット認識コンパイル(JavaScript の Babel のような、現代の CSS を古いブラウザが理解するものにダウンレベリング)でした。2022年にプロジェクトは Lightning CSS に名前変更され、Parcel から独立したスタンドアロンツールとして切り離されました。それは現在 Vite の推奨される現代の CSS パイプライン、Parcel 自体のデフォルト、css-minimizer-webpack-plugin のオプションです。Tailwind の次世代 Oxide エンジンはそれを統合します。
現代の CSS パイプライン
現代の Web プロジェクトはめったにスタイルシートに直接生 CSS を書きません。Sass(Hampton Catlin と Natalie Weizenbaum、2006年最初リリース)、Less(Alexis Sellier、2009)、Stylus(TJ Holowaychuk、2010)はパイプラインの先頭に立ち、変数、ネスティング、ミックスイン、関数、partials を追加します。コンパイラはバニラ CSS を出力し、それは Autoprefixer(Browserslist ベースのベンダープレフィックス適用)、ネストされた CSS の展開、現代の CSS のダウンレベリングのような変換のために PostCSS を通過します。それのすべての後でのみ、ミニファイアが最終的なフラット化された CSS で実行されます。現代のバンドラーはデフォルトで CSS ミニフィケーションを出荷します、webpack 5 は css-minimizer-webpack-plugin(デフォルトでフードの下に cssnano、cssoMinify、cleanCssMinify、esbuildMinify、lightningCssMinify がすべて選択可能)を含みます、Vite はデフォルトで CSS に esbuild を使用し Lightning CSS をオプトインでサポート、Parcel は Lightning CSS を使用、Next.js、Remix、Astro、SvelteKit、Nuxt はすべて開発者の介入なしに本番ビルドにミニフィケーションをバンドルします。結果は、現代のビルドパイプラインを使用する人にとって、CSS ミニフィケーションは自動的に発生するということです。
しかし、誰もがビルドパイプラインを使うわけではありません。多くの WordPress サイト、手書きの HTML ページ、JS toolchain なしの Jekyll/Hugo/Eleventy 静的サイト、webpack の近くに行ったことがない CSS を出荷するワンオフプロジェクト。それらには、ブラウザ内ミニファイアが最低抵抗のパスです、CSS を貼り付け、結果をコピー、デプロイメントを保存。
Critical CSS
知っておくべき補完技術:critical CSS はビューポートの上の領域をレンダリングするのに必要なスタイルのサブセットを識別し、そのサブセットをドキュメントの head の <style> ブロックに直接インライン化し、スタイルシートの残りを非ブロッキングロードに延期する慣行です。うまく行うと、ページは外部スタイルシートの個別のリクエストなしに最初のネットワークラウンドトリップでその初期ビューポートをペイントします。Filament Group は標準的なツールを構築しました、Scott Jehl は2014年7月14日に loadCSS を公開しました、その media 属性を非マッチング値に設定し、ファイルがダウンロードされると all に戻すことでスタイルシートを非同期にロードする小さな JavaScript ユーティリティ。パターンは十分に標準になり、ブラウザは <link rel="preload" as="style" onload="this.rel='stylesheet'"> をそれを表現するより直接的な方法として追加しました。Jason Miller(Preact の作成者)は2018年に GoogleChromeLabs の下で Critters をより高速な代替として公開しました、レンダリングされたページを検査するためにヘッドレスブラウザを実行する代わりに、Critters は静的解析を行います。Critters リポは2024年にアーカイブされ、活発にメンテナンスされているフォークは現在 Beasties 名で Nuxt チームの下で生きています。これらのツールはすべて基礎の CSS が良くミニファイされていることに依存します、ソースシートで節約された各バイトはより小さなクリティカルインラインに繋がります。
レガシーハックは消えた
現代のブラウザはすべて同じ仕様で CSS を解析します。CSS ミニフィケーションを以前にリスキーにした歴史的ハックは本質的に消えました:* html ハックはパーサーバグを悪用して IE6 をターゲットにしました、アンダースコアハック _property: value は IE6 以前をターゲットにしました、*property: value(プロパティ名の前の *)は IE7 以前をターゲットにしました、条件付きコメント <!--[if IE 6]> は特定の IE バージョンに異なるスタイルシートを提供することを許しました、しかし Microsoft は IE10 でその機能を削除しました。IE11 はほとんどの消費者 Windows 10 バージョンで2022年6月15日に寿命に達しました。2026年から、これらのハックは歴史的好奇心であり、CSS ミニファイアはもはやそれらを考える必要はありません。ブラウザ間で同じように空白を削除し、上記の仕様定義された変換を適用する現代のミニファイアは安全です。
このツールが行うこと(と行わないこと)
このツールはシングルファイルブラウザ内ミニファイア、約 30 行の JavaScript です。それは文字列リテラルをプレースホルダーにトークン化して以降のパスがそれらの内容を破損できないようにし、/* ... */ コメントを削除し、{、}、:、;、,、>、~、+ 周りの空白を折りたたみ、} 前の末尾セミコロンを削除し、空白の連続を単一スペースに折りたたみ、各桁ペアが同じ 6 桁の 16 進カラーを 3 桁に短縮し、px、em、rem、%、pt、ex、ch、vw、vh、vmin、vmax のゼロ値から単位を削除します。それは CSS を AST に解析しません、これは regex パスです。それはロングハンドをショートハンドに削減しません。それはセレクタをマージまたは重複排除しません。それは宣言を並べ替えません。それは rgb() を hex に、または名前付きカラーを hex に変換しません。それはキーワードを小文字にしません。それは「重要な」/*! コメントを保持しません、すべてのコメントが同じように削除されます、保持するライセンスヘッダーがある場合は、ミニフィケーション後に手動で貼り付け直してください。それはソースマップを出力しません。正直なフレーミング:エディタや手から出てきた CSS を貼り付け、典型的に生のバイトで 20-40 % 小さい削減バージョンを取り戻し、手作りサイトの素早いデプロイアーティファクトとして使用してください。ビルドパイプラインを持つプロジェクトには、そのパイプラインで cssnano または Lightning CSS を使用してください、持たないプロジェクトには、このツールが摩擦を取り除きます。
なぜブラウザのみがここで重要か
あらゆる Web CSS ミニファイアは同じアーキテクチャ選択を持ちます:作業をサーバーで行うか、ユーザーのブラウザで行うか。サーバー側処理はネットワーク経由でスタイルシートをアップロードする必要があります、つまりその CSS のコピーがサーバーログ、おそらく CDN キャッシュ、おそらく分析パイプライン、おそらくバックアップに残ります。ほとんどの CSS には、これは無害です。内部ツール、未公開製品スタイル、内部クラス分類を明らかにするセレクタを含むシート(.admin-panel-internal-debug-info)には、そうではありません。普通のマーケティングサイト CSS でも、ネットワーク経由で実際に送信するものを監査する開発者は、進行中の作業を自分のマシンに保つことを合理的に好むかもしれません。純粋にブラウザベースのミニファイア、タブで実行され最初のページロード後に決してネットワークリクエストをしない JavaScript、は問題を回避します。確認できます:DevTools の Network タブを開き、CSS を貼り付け、Minify をクリック、発信リクエストを監視します。何も発信しません。さらに良いことに、ページがロードされた後にインターネットから切断(または機内モードを有効化)してもツールはまだ動作します、何もアップロードされていないことの最強の経験的証拠です。
よくある質問
私の CSS はどれくらい縮みますか?
コメントとインデント付きの手書き CSS は通常 20-40 % で縮みます。Sass/Less からコンパイルされて軽くフォーマットされた CSS はより少なく縮みます。PostCSS や Autoprefixer で処理された CSS はしばしば最小限のコメントを持ち、最も少なく縮みます。CDN エッジでの Brotli 圧縮後のサイズはさらにタイトになります、ミニファイされた CSS の Brotli は元の空白の繰り返し度合いに応じて、非ミニファイの Brotli より依然として 5-15 % 多く節約します。
ミニファイされた出力は何かを壊しますか?
通常の CSS には、いいえ、変換は仕様により安全です。自分でチェックする価値のある 2 つのケース:(1)calc()、min()、max()、clamp()、CSS カスタムプロパティ内のゼロ値は単位を剥がされるべきではありません、型付き算術ルールが単位を要求するから、このツールの regex パスは保守的ですが、CSS に calc(0px + 10%) がある場合は出力を見てください。(2)スタイルシートに display: flex; display: grid; のような重複プロパティフォールバックがある場合、このツールは両方を保持します、しかし advanced プリセットの cssnano のような高度なミニファイアは最初のものを削除します。特定のブラウザカスケード動作に依存している場合は、デプロイ前に監査してください。
ライセンスヘッダーを保持しますか?
いいえ。本番ミニファイアは /*!(感嘆符付き)で始まるコメントが「重要」として保持される慣習を尊重します、通常著作権ヘッダーとライセンス通知のため。このツールはすべてのコメントを同じように削除します。ライセンスヘッダー(MIT、GPL、BSD ソース帰属)を必要とする CSS を出荷する場合は、出力にヘッダーを手動で貼り付け直してください。自動保持を必要とするパイプラインには、代わりに cssnano または Lightning CSS を使用してください。
すでにビルドパイプラインを持っている場合これを使うべきですか?
おそらく違います、バンドラがあなたのためにそれを行っています。webpack 5 はフードの下で cssnano を持つ css-minimizer-webpack-plugin を出荷、Vite はデフォルトで CSS ミニフィケーションに esbuild を使用、Parcel は Lightning CSS を使用。このツールはビルドパイプラインがカバーしないケースのためです:手書き HTML、Node toolchain なしで出荷される WordPress テーマ、ミニフィケーションをバンドルしない静的サイトジェネレーター、メールテンプレートまたは素早いデモのためのワンオフ CSS ファイル。それらには、ブラウザ内貼り付けツールが最低抵抗のパスです。
私のファイルはアップロードされますか?
いいえ。ミニファイアはブラウザで実行される JavaScript です。貼り付ける CSS はネットワークを横断しません、Minify をクリックする間に DevTools の Network タブを確認するか、ロード後にページをオフラインにしてもツールがまだ動作することを確認してください。内部スタイルシート、未公開製品スタイル、内部クラス分類を明らかにする CSS はあなたのデバイスに残ります。
後で出力を非ミニファイできますか?
正確には違います、元のコメントと空白は永久になくなりました、それが目的です。しかし、ミニファイされた CSS を再び読みやすくするためにフォーマットできます。Prettier(CSS プラグイン付き)、VS Code の組み込み Format Document コマンド、またはオンラインの「CSS beautifier」ツールはすべてインデントと改行を再挿入します。削除されたコメントを回復することはできません。常に標準形式として非ミニファイソースをバージョン管理に保持してください。