コラム・豆知識
未使用セレクタがもたらすパフォーマンスの低下
CSSファイルに存在するが、実際のHTMLで使用されていないセレクタ(未使用セレクタ)は、読み込みやレンダリング時に不要な負荷を与える可能性があります。
とくに大規模なスタイルシートでは、数百〜数千行に及ぶコードの中に放置された未使用スタイルが蓄積され、ファイルサイズの増加や保守性の低下を招きます。
無駄なCSSを省くことは、表示速度やSEOスコアの向上にもつながります。
開発中に発生しやすい「使い残し」
UIコンポーネントの変更やHTML構造のリファクタリングによって、かつて使用していたCSSセレクタが不要になることはよくあります。
しかし、これらを削除するタイミングを逃すと、コードベースに「使われていないのに残っているスタイル」が散在することになります。
開発チーム内での共有やレビュー時にも混乱を招きやすいため、定期的な検出とクリーンアップが重要です。
セレクタの正確な検出が必要な理由
.btn-primary
や#main-nav
のような単純なセレクタは検出が容易ですが、:hover
や:not()
、.class1.class2
のような複雑なセレクタは、誤判定の原因にもなります。
また、JavaScriptで動的に適用されるクラス名や属性セレクタ(例:[data-state="open"]
)などは静的な解析では見落とされがちです。
そのため、検出ツールは「正確さ」と「柔軟性」を兼ね備えている必要があります。
メンテナンスと再設計に役立つ分析
未使用CSSセレクタの検出は単なる掃除ではありません。
冗長なスタイルがどこで生まれやすいのか、どの部分が設計上のボトルネックになっているのかを見直す機会にもなります。
とくに、コンポーネント単位でスタイルを分割管理しているプロジェクトにおいては、使用状況の可視化がデザインシステムの最適化に直結します。
継続的なクリーンアップの仕組み化
CSSの整理は一度きりの作業ではなく、開発サイクルの中に組み込むべきプロセスです。
ビルド時に未使用セレクタを自動で検出・除外する仕組みや、スタイルガイドに準拠した命名規則を徹底することで、コードのクリーンさを維持しやすくなります。
また、開発終了後の保守フェーズでも、不要スタイルの検出ツールを活用することで、軽量で持続可能なフロントエンド環境を保てます。
ツールの仕組み解説
HTMLとCSSの入力が変更されたとき、自動的に解析を走らせるための仕組みがあります。
document.getElementById('css-input').addEventListener('input', function() { debounceAnalysis(); });
input
イベントを使って、ユーザーが入力欄を変更したときにリアルタイムで解析できるようにしています。
ユーザーが入力中に何度も解析が走らないよう、入力が止まってから500ms後に処理を開始するようになっています。
debounceTimer = setTimeout(function() { analyzeCSS(); }, 500);
これによってパフォーマンスが大幅に向上します。特にCSSやHTMLが大きくなるほど効果的です。
HTMLとCSSの両方が入力されていたら、CSSセレクタを抽出してHTML内で使われているかをチェックします。
const cssSelectors = extractCSSSelectors(cssContent); const results = checkSelectorUsage(cssSelectors, htmlContent);
まずセレクタを取り出し、それぞれがHTML内に実際使われているかどうかを確認する流れです。
CSSコードからコメントや@規則(@keyframes など)を取り除き、実際のセレクタ部分だけを収集しています。
const multipleSelectors = selectorPart.split(','); multipleSelectors.forEach(function(selector) { selectors.add(selector.trim()); });
1つのルールに複数のセレクタが書かれていても、すべてきちんと個別に分けて集めています。
抽出したセレクタがHTMLの中に使われているかを確認します。疑似クラスなどは無視して、クリーンな状態でチェックします。
let cleanSelector = selector.replace(/:+[\w-]+(\([^)]*\))?/g, '').trim();
このようにして、:hover
や::before
などの疑似部分を除いた純粋なセレクタとして判定します。
次に、セレクタがHTMLの中に実際存在するかどうかを、RegExp
を使って判定しています。
const classRegex = new RegExp('class\\s*=\\s*["\']([^"\']*\\s)?' + escapeRegex(className), 'i');
クラス名がclass属性の中に含まれているか、タグ名・ID・属性名がHTML内に存在するかどうかで「使われている」かを判断します。
最終的に、使われていないセレクタをリストアップして、画面に表示します。
displayUnusedSelectors(results.unusedSelectors);
使われているセレクタは一切表示せず、未使用のものだけを絞り込むことで、CSSの整理に集中できるUI設計になっています。
フィルタ欄にキーワードを入力すると、未使用セレクタの中から「含まれているものだけ」または「除外して表示する」ことができます。
const containsText = item.selector.toLowerCase().includes(filterText);