メインコンテンツに移動
クリティカルCSS・未使用CSSとは?表示速度とCSS品質を改善する最適化手法

クリティカルCSS・未使用CSSとは?表示速度とCSS品質を改善する最適化手法

WebサイトやWebアプリの表示速度を改善するとき、多くの人はまず画像圧縮、JavaScriptの削減、サーバー応答速度、キャッシュ設定などに注目します。もちろん、これらはパフォーマンス改善において非常に重要です。しかし、実際のフロントエンド開発では、CSSの読み込み方やCSS設計の状態も、初期表示の速さやUIの安定性に大きく影響します。CSSは見た目を作るためのファイルですが、ブラウザにとっては読み込み、解析し、各要素に適用する必要がある処理対象でもあります。そのため、CSSが大きすぎたり、初期表示に不要なスタイルまで先に読み込んだりすると、ユーザーが最初の画面を見るまでの時間が長くなります。

この問題を考えるときに重要になるのが、**クリティカルCSS(Critical CSS)未使用CSS(Unused CSS)**です。クリティカルCSSは、ページを開いた直後に必要なCSSを優先して読み込ませるための考え方です。一方、未使用CSSは、実際には使われていないCSSを見つけて削減し、CSS全体を軽くするための考え方です。どちらもCSS最適化に関係しますが、目的は少し違います。クリティカルCSSは「最初に必要なものを早く届ける」ための最適化であり、未使用CSS対策は「不要なものを減らして、読み込みや保守の負担を下げる」ための最適化です。

特に大規模なWebサイトや、長期間運用されているWebアプリでは、CSSは少しずつ肥大化していきます。過去に使っていたボタン、削除済みのページ、古いキャンペーン用のレイアウト、以前のデザインシステムの残り、使っていないUIライブラリのスタイルなどが、気づかないうちにCSSファイルへ残り続けます。こうしたCSSは、見た目にはすぐ問題として現れないため放置されやすいですが、表示速度、開発効率、保守性に少しずつ悪影響を与えます。クリティカルCSSと未使用CSSを理解することは、単にページを速くするだけでなく、長期的に管理しやすいCSS基盤を作るためにも重要です。

1. クリティカルCSSとは

クリティカルCSSとは、ページの初期表示に必要な最小限のCSSのことです。特に、ユーザーがページを開いた直後に目にする範囲、つまりファーストビューを正しく表示するために必要なスタイルを指します。たとえば、ヘッダー、ナビゲーション、ファーストビューのレイアウト、メインコピー、主要CTAボタン、背景色、フォントサイズ、余白、画像枠などが含まれます。逆に、ページ下部のフッター、スクロール後に表示されるカード、クリック後に開くモーダル、遅延表示されるアニメーションなどは、初期表示には必ずしも必要ではありません。

ブラウザは、HTMLを読み込んだだけでは完成した画面を表示できません。CSSを取得し、解析し、CSSOMを構築し、それをHTMLのDOMと組み合わせてレンダーツリーを作ります。その後、レイアウト計算、描画、合成という流れで画面が表示されます。つまり、CSSは単なる装飾ではなく、ブラウザが画面を作るために必要な情報です。そのため、初期表示に必要なCSSが大きな外部CSSファイルの中に埋もれていると、ブラウザはファーストビューに関係ないCSSまで読み込み、解析してから描画を進めることになります。クリティカルCSSは、この無駄を減らすために、最初に必要なスタイルだけを優先して届ける設計です。

1.1 クリティカルCSSの基本用語

クリティカルCSSを理解するためには、ファーストビュー、レンダリングブロック、CSSOM、インラインCSSといった用語を整理しておく必要があります。これらはすべて、ブラウザがどのタイミングで画面を描画できるかに関係しています。特にCSSは、見た目の完成度だけでなく、描画開始のタイミングにも影響します。CSSを単なるデザインファイルとして見るのではなく、ブラウザのレンダリング処理に関わる重要なリソースとして理解することが大切です。

英語日本語説明
Critical CSSクリティカルCSS初期表示に必要な最小限のCSS
Above the Foldファーストビュースクロール前にユーザーが最初に見る領域
Render-blocking CSSレンダリングブロックCSS読み込み完了まで描画を遅らせるCSS
Inline CSSインラインCSSHTML内に直接書かれたCSS
CSSOMCSSオブジェクトモデルブラウザがCSSを解析して作る構造
First Paint初回描画画面に最初の要素が表示されるタイミング

クリティカルCSSの本質は、ページ全体のCSSをすべて早く読み込ませることではありません。初期表示に必要なCSSだけを先に届け、後から必要になるCSSは通常読み込みや遅延読み込みに回すことです。この考え方を使うと、ユーザーはページ全体の読み込みが完了する前でも、主要な内容を早く確認できます。つまり、クリティカルCSSは単なるファイルサイズ削減ではなく、表示の優先順位を設計するための考え方です。

1.2 ファーストビューとの関係

ファーストビューとは、ユーザーがページを開いた直後に見る範囲です。LPであれば、ヒーローセクション、キャッチコピー、CTAボタン、ナビゲーションが重要になります。ブログ記事であれば、記事タイトル、リード文、アイキャッチ画像、本文の最初の数行が重要です。ECサイトであれば、ヘッダー、検索バー、商品画像、価格、購入導線などが初期表示の中心になります。このように、ファーストビューに必要なCSSは、ページの目的やユーザーの行動によって変わります。

クリティカルCSSを作るときは、単に画面の上部にある要素だけを見るのではなく、ユーザーが最初に何を理解すべきかを考える必要があります。たとえば、CTAボタンのスタイルが遅れて適用されると、ユーザーは重要な導線を見逃す可能性があります。記事ページでタイトルや本文のフォントが後から大きく変わると、読み始めの体験が不安定になります。ECサイトで商品画像の枠や価格表示が遅れて整うと、購入導線への信頼感も下がります。つまり、ファーストビューのCSSは、単に「見た目を早く出す」だけでなく、ユーザーがページの目的をすぐ理解できる状態を作るために必要です。

1.3 インライン化の意味

クリティカルCSSは、HTMLの<style>タグ内に直接書かれることがあります。これをインライン化と呼びます。インライン化されたCSSは、外部CSSファイルのダウンロードを待たずにブラウザがすぐ利用できるため、初期表示の改善につながります。特に、ネットワークが遅い環境や、外部CSSファイルが大きいサイトでは、ファーストビューに必要なスタイルを先にHTML内へ含めることで、描画開始までの待ち時間を短くできます。

ただし、インライン化は万能ではありません。大量のCSSをHTMLに埋め込むと、HTMLそのものが重くなります。また、外部CSSであればブラウザキャッシュを利用できますが、HTMLに埋め込まれたCSSはページごとに送信されるため、同じCSSが何度も転送されることがあります。その結果、初回表示は少し改善しても、複数ページを回遊するユーザーにとっては効率が悪くなる場合があります。したがって、インライン化するCSSは、ファーストビューを安定させるために本当に必要なものだけに絞る必要があります。

2. 未使用CSSとは

未使用CSSとは、CSSファイルの中には存在しているものの、実際のページや現在のコンポーネントでは使われていないCSSのことです。たとえば、以前は使っていたボタンデザインのclass、削除済みページに対応していたレイアウトCSS、終了したキャンペーン用の装飾、すでに表示されなくなったモーダルやバナーのスタイル、導入したものの一部しか使っていないUIライブラリのCSSなどが該当します。プロジェクトが小さいうちはあまり目立ちませんが、サイト改修、機能追加、デザイン変更、ABテスト、ページ削除などを繰り返すうちに、使われていないCSSは少しずつ蓄積されていきます。最初は数行程度の無駄でも、長期運用の中では数百行、数千行単位の不要CSSになり、CSS全体の見通しを悪くする原因になります。

未使用CSSが増えると、単にCSSファイルの容量が大きくなるだけではありません。ブラウザはそのCSSが実際に画面で使われるかどうかに関係なく、ファイルとして読み込み、解析し、セレクタを照合する必要があります。そのため、読み込み時間やCSSOM構築の負荷が増え、初期表示や操作中の反応にも影響する場合があります。また、開発者にとっても、どのCSSが今も必要で、どのCSSが不要なのか判断しにくくなります。削除してよいか分からないCSSが増えると、修正が慎重になりすぎたり、古いCSSの上にさらに新しいCSSを重ねたりすることになり、結果としてCSSの肥大化が進みます。未使用CSSは、表示速度だけでなく、CSS設計、保守性、チーム開発の効率にまで関係する重要な問題です。

2.1 未使用CSSの基本用語

未使用CSSに関連する用語には、Unused CSS、Dead CSS、CSS Bloat、Purge、Safelist、Tree Shakingなどがあります。これらは同じ文脈で使われることが多いですが、それぞれ少しずつ意味が異なります。Unused CSSは、現在のページやアプリで実際には使われていないCSS全般を指します。Dead CSSは、過去には役割があったものの、現在では使われなくなったCSSを指すことが多いです。CSS Bloatは、不要なCSSや重複したCSSが増えすぎて、CSS全体が必要以上に膨らんでいる状態を表します。Purgeは不要なCSSを削除する処理であり、Safelistは誤って削除されてはいけないclassを保護するための設定です。

英語日本語説明
Unused CSS未使用CSS実際には使われていないCSS
Dead CSSデッドCSS役割を失って残っているCSS
CSS BloatCSS肥大化CSSが必要以上に増えた状態
Purgeパージ不要なCSSを削除する処理
Safelistセーフリスト削除してはいけないclassの指定
Tree Shakingツリーシェイキング未使用コードを除去する最適化

未使用CSSの問題は、ファイルサイズが大きくなることだけに限定されません。不要なCSSが残っていると、古いスタイルが新しいUIに意図せず影響することがあります。特に、.title.button.card.contentのような汎用的なclass名を使っている場合、別のページや古いコンポーネント用に書かれたCSSが、現在のUIにも当たってしまう可能性があります。その結果、本来ならシンプルに設計できるはずのCSSに、上書き用の指定が増えていきます。未使用CSSの削減は、パフォーマンス改善だけでなく、スタイルの衝突を減らし、CSSを読みやすく保つためにも重要です。

2.2 未使用CSSが増える原因

未使用CSSが増える大きな原因は、UIの変更と削除です。WebサイトやWebアプリでは、デザインリニューアル、機能追加、LPの差し替え、キャンペーンページの終了、ABテストの終了、コンポーネントの統合などが頻繁に行われます。そのとき、HTMLやReactコンポーネント、テンプレートファイルは削除されても、対応していたCSSだけが残ってしまうことがあります。CSSは画面上で直接「不要です」と表示されるものではないため、不要になっても気づかれにくく、後回しにされやすい特徴があります。特に、複数人で開発しているプロジェクトでは、「誰かがまだ使っているかもしれない」という不安から、削除されずに残り続けることも多いです。

もう一つの原因は、CSSライブラリやUIフレームワークの導入です。UIライブラリは便利ですが、実際に使うスタイルはその中の一部だけである場合が少なくありません。たとえば、ボタン、グリッド、フォームだけを使っているのに、ナビゲーション、モーダル、ツールチップ、アラート、テーブル、カルーセルなどのCSSまでまとめて読み込んでいるケースがあります。また、過去に使っていたライブラリを一部だけ残していたり、デザイン変更後も古いCSSファイルをそのまま読み込んでいたりすると、CSS全体が必要以上に重くなります。必要なCSSだけを読み込む設計にしないと、プロジェクトが進むほどCSSは自然に肥大化していきます。

2.3 未使用CSSが保守性を下げる理由

未使用CSSが多いと、開発者はCSSを安全に変更しにくくなります。あるclassを削除したいと思っても、「このclassは本当に使われていないのか」「ログイン後の画面やスマートフォン表示では使われていないのか」「古いページでまだ参照されていないのか」と不安になります。その結果、削除すべきCSSを残したまま、新しいCSSを追加する判断になりがちです。この状態が続くと、CSSは減ることなく増え続けます。使われているか分からないCSSが増えるほど、修正時の影響範囲も読みにくくなり、ちょっとしたデザイン変更にも時間がかかるようになります。

また、未使用CSSは新しいデザインの導入を妨げることもあります。古いスタイルが残っていると、新しく作ったコンポーネントに意図しないmargin、padding、font-size、color、line-height、display設定などが当たる場合があります。そのたびに上書きCSSを追加して対応すると、CSSの優先順位が複雑になり、どの指定が最終的に効いているのか分かりにくくなります。こうなると、CSSは「設計されたスタイル」ではなく、「過去の指定を上書きしながら何とか表示している状態」になってしまいます。未使用CSSを減らすことは、表示速度を改善するだけでなく、CSS全体の健康状態を保つためにも欠かせません。

3. クリティカルCSSと未使用CSSの違い

クリティカルCSSと未使用CSSは、どちらもCSS最適化に関係する重要なテーマですが、目的と対象が異なります。クリティカルCSSは、ページを開いた直後に必要なCSSを優先して読み込ませ、ファーストビューをできるだけ早く安定して表示するための考え方です。一方、未使用CSS対策は、プロジェクト内に残っている不要なCSSを見つけて削除し、CSS全体の容量や複雑さを減らすための取り組みです。つまり、クリティカルCSSは「どのCSSを先に届けるか」という読み込み順の最適化であり、未使用CSS対策は「そもそも不要なCSSを減らす」というCSS量と構造の最適化です。

この2つは、どちらか一方だけを行えば十分というものではありません。クリティカルCSSを整えて初期表示を速くしても、CSS全体が巨大なままであれば、後続の読み込み、解析、保守には問題が残ります。逆に、未使用CSSを削除してCSS全体を軽くしても、初期表示に必要なCSSが適切に優先されていなければ、ファーストビューの表示は遅いままです。実務では、まずページの初期表示に必要なCSSを見極め、そのうえでCSS全体の不要部分を減らすという両面の対策が必要になります。両方を組み合わせることで、体感速度と長期的な保守性を同時に改善できます。

項目クリティカルCSS未使用CSS
目的初期表示を速くするCSS容量と保守コストを減らす
対象ファーストビューに必要なCSS実際には使われていないCSS
主な効果FCPやLCPの改善読み込み、解析、管理の改善
主な対策抽出、inline化、遅延読み込み削除、Purge、分割、整理
注意点抽出ミスで初期表示が崩れる動的classを誤削除しやすい

クリティカルCSSは、ユーザーがページを開いた瞬間に必要になるスタイルを選び出す考え方です。たとえば、ヘッダー、ヒーローエリア、タイトル、主要なCTAボタン、最初に見える画像やレイアウトなどが対象になります。一方、未使用CSSは、現在のプロジェクト全体の中で役割を失ったスタイルを見つけて取り除く考え方です。前者は「最初に何を見せるか」に直結し、後者は「プロジェクト全体をどれだけ軽く、管理しやすくするか」に関係します。この違いを理解しておくと、CSS最適化の優先順位を決めやすくなります。

4. なぜCSSが表示速度に影響するのか

CSSは、HTMLの見た目を整えるために必要なものですが、ブラウザにとっては読み込み、解析、適用が必要なリソースでもあります。ブラウザはHTMLを読み込み、CSSファイルを取得し、CSSOMという内部構造を作り、DOMとCSSOMを組み合わせてレンダーツリーを構築します。その後、各要素のサイズや位置を計算し、画面に描画し、必要に応じて合成処理を行います。この流れの途中でCSSの読み込みや解析が遅れると、ページの初期表示も遅くなります。つまり、CSSは見た目を作るだけでなく、ブラウザのレンダリング工程そのものに関わっているのです。

CSSが大きすぎる場合、ネットワークでのダウンロードに時間がかかるだけではありません。ダウンロード後には、ブラウザがCSSを解析し、セレクタを照合し、どの要素にどのスタイルを適用するかを判断する必要があります。さらに、初期表示に不要なCSSまで先に読み込んでしまうと、ユーザーがまだ見ていない部分のスタイルのために、最初の描画が遅れることもあります。特に、巨大なグローバルCSSや複雑なセレクタが多いCSSは、初期表示だけでなく、操作中の再計算にも影響します。CSS最適化がWebパフォーマンスに関係するのは、このようにCSSがレンダリング全体の流れに組み込まれているためです。

4.1 CSSはレンダリングをブロックする

外部CSSは、多くの場合レンダリングをブロックします。ブラウザはHTMLを読み込んだだけでは、最終的な見た目を正しく判断できません。CSSがまだ読み込まれていない状態で画面を描画してしまうと、後からCSSが適用されたときにフォントサイズ、余白、色、レイアウトが大きく変わる可能性があります。そのため、ブラウザはCSSの読み込みが完了するまで描画を待つことがあります。特に、<head>内で読み込まれる大きなCSSファイルは、ファーストビューの表示速度に影響しやすくなります。

この問題を軽減するために使われるのが、クリティカルCSSの考え方です。初期表示に必要なCSSだけを先に提供し、それ以外のCSSを後から読み込むことで、ユーザーが最初に見る部分を早く安定して表示できます。すべてのCSSを同じ優先度で読み込むのではなく、最初に必要なCSS、スクロール後に必要なCSS、操作後に必要なCSSを分けて考えることが重要です。このように読み込み順を整理すると、ページ全体の読み込みが完了する前でも、ユーザーには「早く表示された」と感じてもらいやすくなります。

4.2 CSSOM構築に時間がかかる

CSSはファイルとして読み込まれた後、ブラウザによって解析され、CSSOMという構造に変換されます。CSSOMは、HTML要素にどのCSSルールを適用するかを判断するために必要な内部構造です。CSSルールが多いほど、またセレクタが複雑であるほど、ブラウザは多くの情報を処理する必要があります。たとえば、深い入れ子セレクタや、広範囲に影響する汎用セレクタが多いCSSは、解析や照合の負荷を増やす要因になります。

未使用CSSが多い場合、実際には画面で使われないCSSまでCSSOM構築の対象になります。ユーザーが見ているページでは使われないスタイルであっても、CSSファイルに含まれていれば、ブラウザはそれを読み込み、解析する必要があります。そのため、未使用CSSを減らすことは、単に転送量を減らすだけでなく、ブラウザ内部の処理負荷を下げることにもつながります。特に、モバイル端末や低スペック端末では、CSSOM構築やスタイル計算の負荷が体感速度に影響しやすいため、CSSの整理は重要です。

4.3 スタイル再計算が重くなる

CSSは初期表示だけでなく、ユーザー操作中のパフォーマンスにも影響します。JavaScriptでclassを切り替えたり、DOM要素を追加・削除したり、タブやアコーディオンを開閉したり、モーダルを表示したりすると、ブラウザは必要に応じてスタイルを再計算します。このとき、CSSが複雑で、広い範囲に影響するセレクタが多いと、再計算の負荷が大きくなります。結果として、ボタンを押したときの反応が遅れたり、メニューの開閉がカクついたり、アニメーションが滑らかに動かなかったりすることがあります。

たとえば、ページ全体に影響するセレクタや、深い階層を前提にしたセレクタが多い場合、ブラウザは多くの要素に対してスタイル適用を確認する必要があります。また、不要なCSSが大量に残っていると、実際には使われていないルールであっても、CSS全体の構造が複雑になり、変更時の影響範囲も分かりにくくなります。CSS最適化は、ページを開いた瞬間だけでなく、ユーザーが操作している間の快適さにも関係します。特に、インタラクティブなWebアプリでは、CSSの軽さと整理された構造が重要になります。

4.4 レイアウト崩れにも関係する

CSSの読み込みが遅れると、ページの見た目が後から大きく変化することがあります。たとえば、最初は装飾のないHTMLだけが表示され、その後CSSが適用されてフォントサイズ、余白、画像の表示サイズ、ボタンの位置が変わると、画面全体がガタついて見えます。ユーザーにとって、このような後からのズレは読みづらさや不安定さにつながります。特に、記事ページのタイトル、ヒーロー画像、CTAボタン、ナビゲーションなどが後から動くと、ページ全体の品質が低く見えてしまいます。

クリティカルCSSを適切に用意しておくと、初期表示に必要なレイアウト、余白、フォント、画像枠、ボタンサイズなどを早い段階で安定させられます。特に、ファーストビューの中にある主要コンテンツのサイズや位置が最初から決まっていれば、読み込み中でも違和感の少ない表示になります。表示速度だけを追うのではなく、見た目の安定性を保つこともCSS最適化の重要な目的です。速く表示されても、後から大きく崩れるページはユーザー体験としては良くありません。

5. クリティカルCSSの作り方

クリティカルCSSを作るときは、まず初期表示に必要な範囲を明確にします。対象になるのは、ページを開いた直後にユーザーが目にするヘッダー、メインビジュアル、タイトル、リード文、CTAボタン、基本レイアウト、背景色、フォント設定などです。ここで重要なのは、CSSを小さくすることだけを目的にしないことです。あまりにも削りすぎると、初期表示の見た目が崩れたり、後からCSSが読み込まれたときに大きなレイアウト変化が起きたりします。クリティカルCSSは「最小限でありながら、最初の表示を安定させるCSS」と考える必要があります。

クリティカルCSSは、HTML内にインラインで埋め込む方法がよく使われます。インライン化することで、外部CSSファイルの取得を待たずに、初期表示に必要なスタイルをすぐに適用できます。そのうえで、ページ全体に必要なCSSや、スクロール後に必要なCSS、操作後に必要になるCSSは外部ファイルとして読み込みます。この設計により、初期表示に必要な部分を早く見せつつ、残りのCSSは通常通りキャッシュ可能なファイルとして管理できます。速度と保守性の両方を考えるなら、クリティカルCSSと外部CSSの役割分担が重要です。

5.1 ファーストビューを定義する

クリティカルCSSを作る前に、まず対象ページのファーストビューを定義します。ファーストビューとは、ユーザーがページを開いた直後にスクロールせずに見える範囲のことです。ただし、PC、タブレット、スマートフォンでは画面サイズが異なるため、同じページでも最初に見える範囲は変わります。PCではヒーローエリア全体が見えていても、スマートフォンでは見出しとボタンの一部だけが見えている場合があります。そのため、主要なビューポートごとにファーストビューを確認し、どの要素のCSSを優先すべきかを判断する必要があります。

ファーストビューを定義するときは、画面上部にある要素を機械的に選ぶだけでは不十分です。ページの目的に合わせて、ユーザーが最初に理解すべき情報を考える必要があります。たとえば、LPではキャッチコピーとCTAボタンの視認性が重要です。記事ページではタイトル、リード文、本文の読み始めが重要になります。ECサイトでは商品画像、価格、購入ボタンが重要です。ページごとに「最初に何が正しく見えるべきか」を整理すると、クリティカルCSSに含めるべき範囲を判断しやすくなります。

5.2 必要なCSSだけを抽出する

ファーストビューを決めたら、その表示に必要なCSSだけを抽出します。対象になるのは、bodyの基本設定、フォント、背景色、ヘッダー、ナビゲーション、ヒーロー、タイトル、主要ボタン、初期レイアウトなどです。逆に、ページ下部のカード一覧、フッター、後から表示されるモーダル、スクロール後のアニメーション、詳細な装飾などは、最初から含めすぎないようにします。クリティカルCSSに含めるCSSが多すぎると、HTMLが重くなり、インライン化のメリットが弱くなります。

自動抽出ツールを使うこともできますが、自動抽出だけに頼ると、状態変化やレスポンシブ表示を見落とすことがあります。たとえば、スマートフォンのハンバーガーメニュー、ログイン後のヘッダー、ABテスト中の別デザイン、Cookie同意バナーなどは、抽出時の条件によって含まれない場合があります。そのため、クリティカルCSSは自動化と目視確認を組み合わせて作るのが安全です。ツールで候補を抽出し、実際の画面で崩れがないか確認し、必要に応じて手動で調整する流れが実務では現実的です。

プログラミング言語:HTML

ファイル名:critical-css-example.html

 

<head>
  <style>
    body {
      margin: 0;
      font-family: system-ui, sans-serif;
      background: #ffffff;
      color: #1f2937;
    }

    .site-header {
      height: 64px;
      display: flex;
      align-items: center;
      justify-content: space-between;
      padding: 0 24px;
      border-bottom: 1px solid #e5e7eb;
    }

    .hero {
      min-height: 60vh;
      display: grid;
      place-items: center;
      padding: 48px 24px;
      text-align: center;
    }

    .hero-title {
      max-width: 720px;
      font-size: clamp(32px, 6vw, 64px);
      line-height: 1.1;
      margin: 0 0 20px;
    }

    .hero-button {
      display: inline-flex;
      align-items: center;
      justify-content: center;
      min-height: 48px;
      padding: 0 24px;
      border-radius: 999px;
      background: #111827;
      color: #ffffff;
      text-decoration: none;
      font-weight: 700;
    }
  </style>

  <link rel="stylesheet" href="/assets/main.css">
</head>

 

この例では、初期表示に必要なbody、ヘッダー、ヒーロー、CTAボタンだけをインライン化しています。ページ下部のカード、フッター、モーダル、細かい装飾、スクロール後のアニメーションなどは外部CSSに残す設計です。これにより、ユーザーが最初に見る部分の見た目を早く安定させながら、残りのCSSは通常のファイルとして管理できます。クリティカルCSSは、すべてをHTMLに詰め込むためのものではなく、初期表示の品質を保つために必要なCSSだけを選ぶための考え方です。

5.3 残りのCSSを適切に読み込む

クリティカルCSS以外のCSSは、外部ファイルとして読み込むか、必要に応じて遅延読み込みします。ただし、すべてを遅延読み込みにすればよいわけではありません。後からCSSが適用されることで、スクロール中にカードの高さが変わったり、画像枠がずれたり、フォントサイズが変わったりすると、ユーザーにとって不安定な体験になります。どのCSSを先に読み、どのCSSを後から読み込むかは、ページの構造とユーザーの行動を考えながら決める必要があります。

特に、レイアウトの土台になるCSSは遅延しすぎない方が安全です。画像の表示枠、セクションの基本余白、グリッドの最小幅、カードの基本サイズ、フォントサイズなどが後から変わると、CLSの原因になります。一方で、ページ下部の細かい装飾や、操作後にしか出ないモーダル、スクロール後のアニメーションなどは、初期表示で必ずしも必要ではありません。クリティカルCSSは小さく保つべきですが、初期表示の安定性に必要なスタイルまで削りすぎると逆効果になります。速度と安定性のバランスを取ることが重要です。

6. 未使用CSSの見つけ方

未使用CSSは、手作業だけで正確に見つけるのが難しいです。CSSは1つのページだけで使われるとは限らず、別ページ、ログイン後の画面、モーダル表示時、フォームエラー時、スマートフォン表示時、ダークモード、ABテストの別パターンなどで必要になる場合があります。そのため、現在見ているページで使われていないからといって、すぐに不要と判断するのは危険です。特に大規模サイトでは、あるCSSがどこで使われているかを人間の記憶だけで追うのは難しくなります。

未使用CSSを見つけるには、Chrome DevTools Coverage、Lighthouse、PurgeCSS、ビルド分析ツール、手動レビューを組み合わせるのが効果的です。ツールは削減候補を見つけるために便利ですが、最終的に削除してよいかどうかは、プロジェクトの画面状態やコード構造を確認して判断する必要があります。未使用CSS対策では、ツールの結果をそのまま信じるのではなく、「どの条件で未使用と判定されたのか」「別の状態では使われないのか」を確認する姿勢が重要です。

6.1 Chrome DevTools Coverageを使う

Chrome DevToolsのCoverage機能を使うと、ページ読み込み時にどのCSSが実際に使われたかを確認できます。CSSファイルごとに使用された割合と未使用部分が表示されるため、どのファイルに無駄が多いのかを把握しやすくなります。特に、大きなCSSファイルの中でほとんど使われていない部分がある場合、改善候補として見つけやすくなります。まずはCoverageで大まかな問題箇所を把握し、その後に対象ファイルを詳しく確認する流れが効果的です。

ただし、Coverageの結果は、その時点で表示・操作した範囲に基づいています。ページを開いただけでは、ドロップダウン、モーダル、タブ、アコーディオン、フォームエラー、ログイン後UI、スマートフォンメニューなどのCSSは使われていないと判定されることがあります。そのため、Coverageを見るときは、主要なUI操作を行いながら確認する必要があります。単にページを読み込むだけでなく、メニューを開く、フォームを送信する、エラー状態を出す、レスポンシブ表示を確認するなど、実際のユーザー行動に近い状態で計測することが大切です。

6.2 Lighthouseで候補を確認する

Lighthouseでは、未使用CSSの削減候補が表示されることがあります。これは、初期表示時に読み込まれているCSSのうち、実際にはあまり使われていないものを把握するのに役立ちます。ページ速度の改善を考えるとき、どのCSSファイルが重く、どこから手を付けるべきかを判断する入口になります。特に、複数のCSSファイルを読み込んでいるサイトでは、どのファイルが初期表示に対して過剰なのかを見つける手がかりになります。

ただし、Lighthouseの結果も絶対ではありません。計測時の画面状態、ネットワーク条件、デバイス設定、ページの読み込みタイミング、JavaScriptの実行状態によって結果は変わります。Lighthouseは問題の候補を見つけるためのツールであり、その結果だけをもとにCSSを削除するのは危険です。実際の削除前には、ページ全体のUI、レスポンシブ状態、動的コンポーネント、ログイン後画面などを確認する必要があります。Lighthouseは「削除するCSSを決める道具」ではなく、「調査すべきCSSを見つける道具」と考えると安全です。

6.3 PurgeCSSなどのツールを使う

PurgeCSSのようなツールは、HTML、JavaScript、テンプレートファイル、コンポーネントファイルなどを解析し、使われているclassを検出して、不要なCSSを削除します。Tailwind CSSのように大量のユーティリティclassを生成する仕組みでは、Purgeによって本番CSSを大幅に軽くできる場合があります。特に、開発時には多くのclassを使えるようにしておき、本番ビルド時には実際に使われたclassだけを残す設計と相性が良いです。

しかし、PurgeCSSは静的解析に基づくため、動的に生成されるclassを見落とすことがあります。たとえば、button--${variant}text-${color}-500のように文字列を組み合わせてclassを作る場合、ツールが実際のclass名を正しく把握できない可能性があります。このような場合、本番ビルド後に必要なCSSが消えてしまい、ボタンの色や状態表示が崩れることがあります。PurgeCSSを使う場合は、動的classの扱い、safelistの設定、削除後のUI確認をセットで行う必要があります。

7. 未使用CSS削除の注意点

未使用CSSの削除は効果的ですが、誤って必要なCSSを削除すると、UIが壊れるリスクがあります。特に、初期表示では見えないが操作後に必要になるCSS、JavaScriptで付与される状態class、CMSが自動出力するclass、外部ライブラリが生成するclass、レスポンシブ専用のclassなどは注意が必要です。ツール上では未使用に見えても、実際のユーザー操作では必要になる場合があります。未使用CSS削除は、単純な掃除ではなく、UIの状態を理解しながら行う作業です。

そのため、未使用CSSを削除するときは、削除前に対象範囲を確認し、削除後にUI回帰テストを行う必要があります。通常表示だけでなく、ホバー、アクティブ、フォーカス、エラー、ローディング、モーダル表示、メニュー開閉、タブ切り替え、レスポンシブ表示など、複数の状態を確認することが大切です。CSSは見た目の品質に直結するため、削除による影響が一見分かりにくい場合でも、細かい状態で崩れが起きていることがあります。安全に削除するには、ツール、コード確認、目視確認の組み合わせが必要です。

7.1 動的classを削除しない

JavaScriptやテンプレートで動的にclass名を作っている場合、未使用CSS削除ツールがそのclassを検出できないことがあります。たとえば、ボタンの種類によってbutton--primarybutton--dangerbutton--ghostのようなclassを生成する場合、実行時には必要でも、ビルド時の静的解析では見つからない可能性があります。特に、propsや状態によってclass名を組み立てるUIでは、この問題が起きやすくなります。

この問題を防ぐには、動的classを完全な文字列としてコード内に書く、variantとclassの対応表を用意する、またはsafelistを設定する方法があります。たとえば、button--${variant}のように文字列結合で作るのではなく、variantClassMap.primaryのように明示的な対応表を使うと、ツールがclass名を検出しやすくなります。デザインシステムでvariant、theme、size、stateを使ってclassを切り替える場合は、削除対象から守るべきclassを事前に整理しておくことが重要です。

プログラミング言語:TypeScript

ファイル名:dynamic-class-example.tsx

 

type ButtonProps = {
  variant: "primary" | "danger" | "ghost";
};

export function Button({ variant }: ButtonProps) {
  const className = `button button--${variant}`;

  return (
    <button className={className}>
      Submit
    </button>
  );
}

 

このようなコードでは、.button--primary.button--danger.button--ghostがCSS内に必要になります。しかし、ツールによっては文字列結合の結果を正しく検出できません。開発中は問題なく見えていても、本番ビルドでPurge処理が走った後に、特定のvariantだけスタイルが消えることがあります。動的classを使う場合は、CSS削除ツールの設定とコードの書き方をセットで考える必要があります。

7.2 safelistを設定する

safelistとは、未使用CSS削除ツールに対して「このclassは削除してはいけない」と明示する設定です。モーダル、タブ、状態表示、アニメーション、外部ライブラリ、CMS出力、JavaScriptで付与されるclassなど、静的解析で検出されにくいclassはsafelistに入れておくと安全です。特に、is-activeis-openis-loadingis-disabledのような状態classは初期表示では使われていないことも多いため、誤って削除されやすいです。

ただし、safelistを増やしすぎると、未使用CSS削減の効果が下がります。何でもsafelistに入れてしまうと、本当に不要なCSSまで残ってしまい、Purgeの意味が弱くなります。そのため、safelistは「静的解析では検出されにくいが、実行時には確実に必要になるclass」を中心に登録します。正規表現を使って、modal-で始まるclassや、theme-で始まるclass、外部ライブラリが生成するclassをまとめて保護する方法もあります。重要なのは、safelistを場当たり的に増やすのではなく、プロジェクト内のclass命名ルールと合わせて管理することです。

プログラミング言語:JavaScript

ファイル名:purgecss-config.js

 

module.exports = {
  content: [
    "./src/**/*.html",
    "./src/**/*.tsx",
    "./src/**/*.jsx"
  ],
  css: [
    "./src/styles/**/*.css"
  ],
  safelist: [
    "is-active",
    "is-open",
    "is-disabled",
    "button--primary",
    "button--danger",
    /^modal-/,
    /^theme-/,
    /^swiper-/
  ]
};

 

この設定では、状態class、ボタンvariant、モーダル、テーマ、外部ライブラリ由来のclassを保護しています。実務では、プロジェクト内で動的に使われるclassのルールを整理し、safelistをチームで管理することが重要です。誰かが一時的に追加したclassをそのままsafelistに残し続けると、不要CSSが再び増えていきます。そのため、safelistも定期的に見直し、本当に必要なものだけを残す運用が必要です。

7.3 状態classを確認する

状態classとは、UIの状態によって付け替えられるclassです。たとえば、is-activeis-openis-loadingis-disabledis-currenthas-errorなどがあります。これらは初期表示では使われないことも多く、未使用CSSとして検出されやすいclassです。しかし、状態classはユーザー操作に応じて重要な役割を持ちます。タブの選択状態、メニューの開閉状態、フォームエラー、ローディング表示、ボタンの無効状態などは、状態classによって見た目が変わることが多いです。

状態classが削除されると、通常表示では問題なく見えても、操作後のUIが崩れる可能性があります。たとえば、メニューを開いても表示されない、モーダルの背景が暗くならない、エラー入力欄が赤くならない、現在位置を示すナビゲーションが強調されない、といった問題が起こります。未使用CSS削除後は、静止画の見た目だけでなく、ユーザー操作後の状態まで確認する必要があります。CSS最適化では、今見えている画面だけで判断しないことが大切です。

8. CSS分割との関係

クリティカルCSSと未使用CSS対策は、CSS分割と強く関係します。CSSが1つの巨大なファイルにまとまっていると、どのCSSが初期表示に必要で、どのCSSがページ固有で、どのCSSが現在使われていないのか判断しにくくなります。その結果、クリティカルCSSの抽出も、未使用CSSの削除も難しくなります。巨大なCSSファイルは一見管理が楽に見えますが、長期的には変更の影響範囲が読みにくくなり、不要CSSが残りやすい構造になります。

CSSを役割ごとに分けておくと、最適化しやすくなります。たとえば、reset、tokens、theme、layout、components、pages、utilities、motionのようにレイヤーを分けると、それぞれのCSSが何のために存在するのか分かりやすくなります。これにより、初期表示に必要なCSSだけを抽出しやすくなり、使われなくなったページ固有CSSも見つけやすくなります。CSS分割は、単にファイルを細かく分けることではなく、CSSの責任範囲を明確にするための設計です。

8.1 レイヤーごとにCSSを分ける

CSSをレイヤーごとに分けると、修正時の影響範囲を把握しやすくなります。たとえば、色や余白、フォントサイズなどの基本値を変更したい場合はtokens.cssを確認し、サイト全体のテーマを調整したい場合はtheme.cssを確認し、ページ固有のレイアウトを直したい場合はpages.cssを見る、というように責任範囲を分けられます。これにより、似たようなCSSを複数箇所に書くことが減り、不要な上書きも防ぎやすくなります。

また、クリティカルCSSを抽出するときにも、レイヤー分割は役立ちます。ファーストビューに必要なlayout、header、hero、buttonのCSSだけを抽出し、下部コンテンツやモーション関連のCSSは後から読み込む、という設計がしやすくなるからです。CSSを最適化しやすい構造にしておくことは、後からの改善コストを下げることにもつながります。最初からCSSの置き場所を決めておけば、不要CSSの発生も抑えやすくなります。

ファイル役割
reset.cssブラウザ差を整える
tokens.css色、余白、フォント、角丸などの変数
theme.cssテーマやブランド別の見た目
layout.css全体構造、グリッド、セクション
components.cssボタン、カード、モーダルなど
pages.cssページ固有のスタイル
utilities.css小さな補助class
motion.cssアニメーションやトランジション
critical.css初期表示に必要な最小CSS

このように分けることで、CSSの役割が明確になります。巨大なCSSファイルを後から分解するのは大変ですが、最初から分割方針を持っておけば、未使用CSSの発生も抑えやすくなります。特に、長く運用するWebサイトや、複数人で開発するWebアプリでは、CSSの分割方針が保守性に大きく影響します。ファイルを分ける目的は数を増やすことではなく、どこに何を書くかを明確にすることです。

8.2 ページ単位で読み込む

すべてのページで同じCSSを読み込むと、あるページでは不要なCSSまで読み込まれることがあります。たとえば、トップページでは使わないフォームCSS、記事ページでは使わないLP用のヒーローCSS、管理画面でしか使わないテーブルCSSなどを全ページで読み込んでいると、初期表示に余計な負荷がかかります。ページ単位でCSSを分けると、そのページに必要なCSSだけを読み込みやすくなります。

ただし、CSSを細かく分けすぎると管理が複雑になります。共通コンポーネントのCSSが複数ファイルに分散しすぎると、修正時にどこを変更すればよいか分かりにくくなります。また、読み込むCSSファイルが増えすぎると、ビルドや運用のルールも複雑になります。実務では、共通CSS、ページ固有CSS、遅延読み込みCSSのバランスを考えることが重要です。細かく分けること自体が目的ではなく、読み込み効率と保守性を両立することが目的です。

9. フレームワークでの対策

React、Next.js、Vue、Nuxt、Astroなどのフレームワークでは、CSSの扱い方がそれぞれ異なります。CSS Modules、CSS-in-JS、Tailwind CSS、グローバルCSS、コンポーネントスコープCSSなど、採用する方式によって最適化の方法も変わります。ただし、基本的な考え方は同じです。初期表示に必要なCSSを優先し、不要なCSSを減らし、動的classを誤って削除しないようにすることが重要です。フレームワークを使っていても、CSS設計が曖昧であれば、CSSは簡単に肥大化します。

フレームワークを使う場合、ビルド時のCSS分割やコンポーネント単位のCSS管理を活用できることがあります。これにより、手動で巨大なCSSを管理するよりも効率的に最適化できる場合があります。ただし、フレームワーク任せにすると、グローバルCSSが肥大化したり、CSS-in-JSのランタイムコストが増えたり、Tailwindの動的classが本番ビルドで消えたりすることもあります。便利な仕組みを使うほど、どのCSSがどのタイミングで生成・読み込み・削除されるのかを理解しておく必要があります。

9.1 CSS Modules

CSS Modulesは、コンポーネント単位でCSSを管理しやすい方式です。class名がローカルスコープ化されるため、グローバルなclass名衝突を減らせます。たとえば、複数のコンポーネントで.titleというclassを使っても、ビルド後には別々のclass名として扱われるため、意図しない上書きが起こりにくくなります。大規模なReactやNext.jsのプロジェクトでは、コンポーネントごとにスタイルを閉じ込められる点が大きなメリットになります。

CSS Modulesを使うと、コンポーネントとCSSの関係が分かりやすくなります。あるコンポーネントを削除するとき、そのCSSも一緒に削除しやすくなるため、未使用CSSを減らしやすい設計になります。ただし、コンポーネントを削除してもCSSファイルだけ残してしまえば、未使用CSSは発生します。また、共通化すべきスタイルを各コンポーネントに重複して書きすぎると、別の形でCSSが増えてしまいます。CSS Modulesを使う場合も、共通トークンや共通コンポーネントの設計は必要です。

9.2 CSS-in-JS

CSS-in-JSは、JavaScriptやTypeScriptの中でスタイルを定義する方式です。コンポーネントのロジックとスタイルを近い場所で管理できるため、UI単位での開発に向いています。propsや状態に応じてスタイルを変えやすく、テーマ切り替え、ダークモード、状態別デザインなども実装しやすいです。コンポーネントの削除と同時にスタイルも削除しやすいため、設計次第では未使用CSSを減らしやすくなります。

一方で、CSS-in-JSはライブラリや設定によってランタイムコストが発生する場合があります。特に初期表示時にスタイル生成が重くなると、パフォーマンスに影響することがあります。また、SSR時のスタイル抽出が適切でないと、初期表示で一瞬スタイルが当たらない、hydration時に見た目が変わる、重複スタイルが増えるといった問題が起きることもあります。CSS-in-JSを使う場合は、見た目の管理しやすさだけでなく、SSR、キャッシュ、重複生成、バンドルサイズへの影響も確認する必要があります。

9.3 Tailwind CSS

Tailwind CSSは、ユーティリティclassを組み合わせてUIを作るCSSフレームワークです。本番ビルドでは、使用されているclassだけを生成する仕組みがあるため、未使用CSS削減と相性が良いです。適切に設定すれば、大量のユーティリティclassの中から実際に使われているものだけをCSSに含められます。そのため、従来のCSSフレームワークのように、使っていないコンポーネントCSSまで読み込む問題を減らしやすくなります。

ただし、Tailwindでも動的classには注意が必要です。たとえば、text-${color}-500bg-${theme}-600のように文字列結合でclass名を作ると、ビルド時に検出されず、必要なCSSが生成されない場合があります。その結果、開発環境では見えていた色や余白が、本番環境で反映されないことがあります。Tailwindを使う場合は、class名をできるだけ静的に書くか、必要な動的classをsafelistに入れる設計が必要です。便利なユーティリティ設計を活かすためにも、ビルド時のclass検出ルールを理解しておくことが重要です。

9.4 Next.js

Next.jsでは、ページ単位の分割、SSR、SSG、App Router、コンポーネント単位のCSS管理などを活用してCSSを最適化できます。ページやコンポーネントごとに必要なCSSを分けやすいため、初期表示に不要なCSSを減らしやすい構造を作れます。また、SSRと組み合わせることで、初期HTMLと必要なスタイルを適切に届けやすくなり、ファーストビューの表示品質を高めやすくなります。

ただし、Next.jsを使っていても、グローバルCSSが大きくなりすぎると最適化効果は下がります。すべてのスタイルをglobal.cssに入れてしまうと、ページ単位の分割が効きにくくなり、どのページでも不要なCSSを読み込む状態になります。共通CSS、ページ固有CSS、コンポーネントCSS、テーマCSSを分け、どのCSSをどこで読み込むかを意識することが重要です。Next.jsの機能を使えば自動的に最適化されるわけではなく、CSS設計の方針があって初めて効果を発揮します。

10. パフォーマンス指標との関係

クリティカルCSSと未使用CSSは、Webパフォーマンス指標にも影響します。特に、FCP、LCP、CLS、INPなどは、CSSの読み込み方、スタイル計算、レイアウトの安定性と関係があります。CSS最適化は、単にファイルサイズを小さくする作業ではありません。ユーザーがページを開いたときにどれだけ早く内容を認識できるか、表示中にレイアウトがずれないか、操作したときにスムーズに反応するかといった体験全体に関わる改善です。

たとえば、クリティカルCSSを適切に用意すると、最初の描画が早くなり、FCPの改善につながることがあります。ファーストビューのメインコンテンツが早く安定して表示されれば、LCPにも良い影響を与える可能性があります。一方で、CSSの遅延読み込みを誤ると、後からレイアウトが変わり、CLSが悪化する場合があります。また、CSSが複雑すぎると、操作時のスタイル再計算が重くなり、INPに影響する可能性もあります。CSS最適化では、速度、安定性、操作性をまとめて考える必要があります。

指標CSSとの関係
FCP最初の描画がCSS読み込みに影響される
LCPメインコンテンツの表示速度に関係する
CLSCSS遅延や後読み込みでレイアウトずれが起きる
INP重いスタイル再計算が入力応答に影響する
TBTCSSそのものよりJS寄りだが、重いUI処理と関係する

CSS最適化では、数値だけを追うのではなく、実際の表示体験も確認する必要があります。たとえば、スコア上は改善していても、読み込み中にボタンの位置がずれたり、フォントが後から変わったり、画像枠が一瞬潰れたりすると、ユーザーにとっては不安定な体験になります。逆に、数値の改善幅が小さくても、ファーストビューがすぐに整って見えるようになれば、体感品質は大きく向上する場合があります。パフォーマンス指標と目視確認を組み合わせることが大切です。

11. よくある失敗

クリティカルCSSと未使用CSS対策は効果的ですが、やり方を間違えると逆に表示崩れや保守性低下につながります。特に、自動化ツールを過信したり、1ページだけの確認でCSSを削除したり、初期表示だけを優先しすぎたりすると、別の問題が発生します。CSSは複数の画面状態、デバイス、ユーザー操作に関係するため、単純に「使われていないように見えるから削除する」という判断では危険です。

CSS最適化では、「削ること」や「速くすること」だけを目的にしないことが大切です。必要な見た目を保ち、状態変化を壊さず、後から管理できる形にすることが重要です。速度改善とUI品質を両立するためには、設計、計測、確認、運用をセットで考える必要があります。短期的な軽量化だけを狙うと、後から表示崩れや保守コストの増加として返ってくることがあります。

11.1 すべてをinline化する

クリティカルCSSを意識しすぎて、大量のCSSをHTMLに埋め込んでしまうケースがあります。確かに、インラインCSSは外部ファイルのダウンロードを待たずに使えるため、初期表示には有利な場合があります。しかし、すべてのCSSをHTMLに入れてしまうと、HTML自体が重くなり、ページごとの転送量が増えます。また、外部CSSのようにブラウザキャッシュを活用しにくくなるため、複数ページを回遊するサイトでは逆効果になることもあります。

特に複数ページで同じCSSを使う場合、外部CSSであれば一度キャッシュされますが、インライン化されたCSSはページごとにHTMLの一部として送信されます。その結果、初回表示は少し改善しても、全体の転送量や保守性が悪化する可能性があります。クリティカルCSSは最小限にし、再利用されるCSSは外部ファイルとして管理する方が安全です。重要なのは、すべてをインライン化することではなく、最初の表示に必要なCSSだけを適切にインライン化することです。

11.2 purgeで動的UIを壊す

未使用CSS削除ツールを使うと、動的classや状態classが削除されることがあります。初期表示では問題なく見えても、メニューを開いたとき、モーダルを表示したとき、タブを切り替えたとき、フォームエラーが出たときに表示が崩れる場合があります。これは、ツールがそのclassを「使われていない」と判断して削除してしまうためです。特に、JavaScriptで後から付与されるclassや、ユーザー操作後に初めて使われるclassは注意が必要です。

この問題を防ぐには、削除後に主要なUI状態を確認する必要があります。通常状態だけでなく、開閉状態、選択状態、エラー状態、ローディング状態、スマートフォン表示などを確認します。また、必要な動的classはsafelistで保護し、削除ツールの設定をプロジェクトに合わせて調整することが重要です。Purgeは強力な最適化ですが、UIの状態を理解せずに使うと、見えないところで重要なスタイルを壊す可能性があります。

11.3 Coverageだけで削除判断する

Chrome DevTools Coverageは便利ですが、CoverageだけでCSS削除を判断するのは危険です。Coverageは、その時点で表示・操作された範囲をもとにCSSの使用状況を判定します。つまり、まだ開いていないモーダル、スクロール後のコンテンツ、ログイン後のUI、別デバイスのレイアウト、ダークモードなどは、未使用として表示される可能性があります。結果だけを見ると大量のCSSを削除できそうに見えても、実際には別の状態で必要なCSSが含まれていることがあります。

Coverageは削除候補を見つけるための入口として使うべきです。実際に削除する前には、そのCSSが別ページや別状態で使われていないかを確認する必要があります。特に大規模サイトでは、1ページだけの結果でCSSを削除すると、別ページの表示が崩れる可能性があります。Coverageで候補を見つけ、コード検索やコンポーネント確認、UIテストと組み合わせて判断することが安全です。

11.4 CSS設計を後回しにする

CSS最適化を後回しにすると、後から整理するのが難しくなります。最初は小さなCSSでも、ページやコンポーネントが増えるにつれて、共通CSS、ページ固有CSS、一時的な上書きCSS、ライブラリ由来のCSSが混在していきます。その状態で未使用CSSを削除しようとしても、どのCSSが何のためにあるのか分かりにくくなります。結果として、削除が怖くなり、さらに上書きCSSを追加する流れになりがちです。

CSS設計は、パフォーマンス改善の土台です。レイヤー分割、命名規則、コンポーネント単位の管理、動的classの扱い、safelistの運用などを早い段階で決めておくと、後からCSSを軽くしやすくなります。CSS最適化は、最後に行う掃除ではなく、日々の設計の中に組み込むべきものです。最初から整理しやすいCSS構造を作っておくことで、表示速度の改善も保守性の向上も進めやすくなります。

12. 実務での運用ルール

実務では、クリティカルCSSと未使用CSS対策を一度だけ行って終わりにしないことが重要です。Webサイトやアプリは継続的に更新されるため、新しいページ、コンポーネント、キャンペーン、ABテスト、デザイン変更が重なると、CSSは自然に増えていきます。一度CSSを整理しても、その後の運用ルールがなければ、数か月後にはまた同じようにCSSが肥大化してしまいます。CSS最適化は単発の作業ではなく、継続的な品質管理として考える必要があります。

チーム開発では、CSSの追加ルール、削除ルール、命名規則、レビュー観点、計測方法を決めておくと、CSSの肥大化を防ぎやすくなります。特に、デザイナー、フロントエンドエンジニア、マーケティング担当者、CMS運用者が関わるサイトでは、CSS変更の影響範囲が広くなりやすいため、運用ルールが重要です。誰がどのCSSを追加しても、同じ方針で管理できる状態を作ることが、長期的なパフォーマンスと保守性につながります。

12.1 CSS追加時のルールを決める

新しいCSSを追加するときは、どのレイヤーに追加するのかを決める必要があります。共通コンポーネントなのか、ページ固有のスタイルなのか、一時的なキャンペーン用CSSなのか、テーマ用のCSSなのかによって、置き場所は変わります。置き場所が曖昧だと、後から未使用CSSを探すのが難しくなります。特に、急いで追加したCSSをglobal.cssに入れ続けると、やがてどのページにも関係する巨大なCSSファイルになってしまいます。

また、似たようなスタイルがすでに存在する場合は、新しくclassを増やす前に再利用できないか確認します。CSSが肥大化する原因の一つは、同じようなボタン、カード、見出し、余白指定を何度も別名で作ることです。デザインシステムや共通コンポーネントを活用すると、重複CSSを減らしやすくなります。CSSを追加する前に「これは既存のトークンやコンポーネントで表現できないか」を確認するだけでも、CSSの増加をかなり抑えられます。

12.2 定期的にCSSを棚卸しする

CSSは、定期的に棚卸しすることで肥大化を防げます。特に、デザインリニューアル後、大きな機能削除後、キャンペーン終了後、ページ構成変更後、UIライブラリの差し替え後は、未使用CSSが増えやすいタイミングです。このようなタイミングでCoverageやLighthouseを使い、不要なCSSを確認すると効果的です。定期的な棚卸しを習慣化すれば、CSSが手に負えないほど大きくなる前に整理できます。

棚卸しでは、単に削除候補を探すだけでなく、CSSの構造も見直します。重複しているスタイルはないか、汎用classが増えすぎていないか、ページ固有CSSが共通CSSに混ざっていないか、動的classがsafelistで管理されているかを確認します。CSS品質を保つには、ファイルサイズだけでなく、設計の見通しも重要です。削除できるCSSを減らすだけでなく、今後不要CSSが増えにくい構造にすることが、本当の意味での改善になります。

12.3 UI回帰テストを組み合わせる

CSS削除やCSS分割を行うときは、UI回帰テストが重要です。CSSは見た目に直結するため、削除や変更による影響がすぐに分からない場合があります。特に、状態変化のあるUIやレスポンシブ表示では、通常状態だけ確認しても不十分です。ある画面では問題なく見えても、スマートフォン表示、エラー状態、モーダル表示、ホバー状態では崩れている可能性があります。

スクリーンショット比較、主要画面の確認、コンポーネントカタログでの確認、手動チェックリストなどを組み合わせると、安全にCSSを整理できます。モーダル、ドロップダウン、タブ、アコーディオン、フォーム、トースト、レスポンシブメニューなどは、CSS削除の影響を受けやすいため、重点的に確認する必要があります。CSS最適化を安全に進めるには、削除する勇気だけでなく、壊れていないことを確認できる仕組みが必要です。

13. グロッサリー

CSS最適化では、似たような用語が多く出てきます。クリティカルCSS、未使用CSS、CSSOM、Purge、Safelist、CLS、FCP、LCPなどは、どれもWebパフォーマンスやCSS設計と関係する言葉です。用語の意味を整理しておくと、何を改善しようとしているのか、どの問題に対してどの対策が有効なのかを理解しやすくなります。特に、パフォーマンス改善では似た言葉が混ざりやすいため、基本的な意味を押さえておくことが重要です。

グロッサリーは、チーム内の共通認識を作るためにも有効です。CSS最適化はフロントエンドエンジニアだけでなく、デザイナー、SEO担当者、マーケティング担当者、プロダクト担当者とも関係します。たとえば、CLSが悪いと言われたときに、それが単なる速度の問題ではなく、レイアウトの安定性の問題だと理解できれば、改善方針も立てやすくなります。用語の理解がそろっていると、改善施策の優先順位やレビュー観点を共有しやすくなります。

用語意味
クリティカルCSS初期表示に必要な最小限のCSS
未使用CSS実際には使われていないCSS
ファーストビューページ表示直後に見える範囲
レンダリングブロック読み込み完了まで描画を待たせる処理
CSSOMCSSを解析して作られるブラウザ内部構造
Purge未使用CSSを削除する処理
Safelist誤削除を防ぐために残すclass指定
CLSレイアウトずれを測る指標
FCP最初の描画までの時間
LCPメインコンテンツ表示までの時間
INP入力応答性を測る指標
CSS BloatCSSが肥大化した状態
Dead CSS役割を失って残っているCSS

おわりに

クリティカルCSSと未使用CSSは、どちらもWebサイトやWebアプリの表示速度を改善するために重要な考え方です。クリティカルCSSは、初期表示に必要なCSSを優先して読み込ませることで、ユーザーが早く主要な画面を見られるようにします。未使用CSSは、実際には使われていないCSSを減らすことで、読み込み時間、解析負荷、保守コストを下げます。

ただし、どちらも単独のテクニックとして扱うだけでは十分ではありません。クリティカルCSSを作っても、CSS全体が肥大化していれば長期的な保守性は改善されません。未使用CSSを削除しても、初期表示に必要なCSSが正しく優先されていなければ、ファーストビューの表示は遅いままです。重要なのは、CSS全体の設計、読み込み順、削除ルール、確認フローをまとめて考えることです。

実務では、CSSは時間とともに増え続けます。新しいページ、コンポーネント、キャンペーン、ABテスト、デザイン変更、フレームワーク更新などが重なると、未使用CSSや重複スタイルは自然に蓄積されます。そのため、CSS最適化は一度だけ行う作業ではなく、継続的なメンテナンスとして扱う必要があります。

クリティカルCSSによって初期表示を安定させ、未使用CSS対策によってCSS全体を軽くし、CSS分割やsafelist、UI回帰テストを組み合わせることで、表示速度とUI品質を両立できます。CSS最適化は、単にコードを削る作業ではありません。ユーザーにとって快適で、開発者にとって扱いやすく、長期運用にも耐えられるUI基盤を作るための設計です。

LINE Chat