パフォーマンスと効率を考慮した CSS の設定方法 10 項目

CSS のイメージ。

パフォーマンスを低下させる CSS の設定を排除して最適化することで、ページの描画速度を改善し、データサイズを小さくすることができます。 ここではパフォーマンスを低下させる CSS の設定例と、それを改善するための設定例を一覧します。

スタイルの値

数値の指定は小数点で

データサイズを小さくするため、0.8 などの 0 ~ 1 の値は .8 で指定します。0 はなくても小数点で解釈されます。

ただし、YUI Compressor などの CSS 圧縮ツール(プログラム)を使えば .8 に圧縮してくれます。 可読性のために、0.8 を設定し、ツールによって圧縮する、というコーディング方法があります。

色の設定はできるだけ短く

例えば #ffffff#fff でも同じ値になります。データサイズを小さくするため、より短い色のコードを指定します。

ただし、YUI Compressor などの CSS 圧縮ツール(プログラム)を使えば #fff に圧縮してくれます。 可読性のために、#ffffff を設定し、ツールによって圧縮する、というコーディング方法があります。

継承を活用する

いくつかのプロパティはその子孫要素に継承されます。 継承されるプロパティを子孫要素で再定義することはパフォーマンスを低下させます。 font やそれに関連する CSS プロパティは、継承されるプロパティの代表的な例です。

他に、background-color などのプロパティは継承されないものの、それより上に配置される要素の背景になります。 <div><p> p 要素が div 要素よりも上に配置される </p></div> のとき、 div 要素に設定した background-color を p 要素にも同じように設定することは非効率です。

セレクタ

基本ルール

(1) セレクタは右から左に解釈されます。

(2) 要素、id、class の順に優先されます。

(3) !important が設定されるとき、最優先されます。

(4) 優先順位が等しいとき、最後に定義されたスタイルが適用されます。

id セレクタは使わない

id セレクタ # を使うと、id セレクタで設定されたスタイルを上書きしにくくなります。 例えば、#id-selector の設定を上書きするためには、p#id-selector のようにタイプセレクタを追加するか、 #id-selector によって再定義するか、!important を使うことになります。

このように id セレクタを使うと、セレクタや CSS 全体が煩雑化する傾向にあるため、id セレクタを使わない、というコーディングルールがあります。 このコーディングルールは、概ね良好なコーディングルールと思われます。 (ただし id セレクタは JavaScript で活用するために使う)

id セレクタの方が処理速度が早いという見方がありますが、昨今のブラウザでは微々たる差でしょう。 もし必要ならページ全体のレイアウトを定める程度に収めるべきです。

id, class セレクタとタイプセレクタを組み合わせない

li.list-item のようなセレクタは非効率です。少なくとも 2 つのパターン li.list-item を走査することになります。

単に .list-item にすれば、走査するパターンは 1 つに収まり、また、要素が変更されても css を変更する必要がありません。 id セレクタを使う場合も同様です。

全称セレクタは使わない

特別な理由がない限り、全称セレクタ * は使いません。 すべての要素(タイプ)にマッチするこのセレクタは、走査・マッチするパターン数を大幅に増やし、パフォーマンスを低下させます。

全称セレクタを使わなければ、スタイルの定義が爆発的に増えてしまう、といったパターンでない限り、使用を控えるべきです。

ファイルサイズが極端に大きくなり、通信に時間かかってしまうようなら、全称セレクタを使ってでも、ファイルサイズを小さくするべき、ということです。

制限されないセレクタは使わない

[class=^"class-name-"] のように正規表現を用いるようなセレクタは、走査する条件を大幅に増やし、パフォーマンスを低下させます。

制限されないセレクタ(正規表現セレクタ)を使わなければ、スタイルの定義が爆発的に増えてしまう、といったパターンでない限り、使用を控えるます。

ファイルサイズが極端に大きくなり、通信に時間かかってしまうようなら、 制限されない正規表現セレクタを使ってでも、ファイルサイズを小さくするべき、ということです。

ワイルドカードを含めた正規表現を使わなければ、全称セレクタほどはパフォーマンスを低下させないでしょう。 便利なセレクタですから、多用しなければ昨今の環境では気にならないんじゃないか、とも思います。

子孫セレクタを多用しない

a img のような子孫セレクタは便利ですが、多用するべきではありません。 走査・マッチするパターン数が増え、パフォーマンスを低下させます。

可能なら、a > img のような子セレクタが使えないか検討します。 ネストが深く、頻出する要素については、class の設定を検討します。

セレクタの階層を深くしない

子孫セレクタや子セレクタを多用して、階層(ネスト)を深くするべきではありません。 走査するパターン数が増え、パフォーマンスを低下させます。

ネストが深くなるときは、短い class セレクタで解決できないか検討します。

×.menu .menu .menu
.menu > .menu > .menu
.descendant-menu

あまりに冗長な名前を付けざるを得ないときは、メンテナンス性を優先し、妥協しても良いと思います。 ただし、そのような要素がページに繰り返し出現するようなら、やはりパフォーマンスのために短い class セレクタを設定するべきでしょう。

連結したセレクタは使わない

.class-a.class-b のように、複数の class を設定して、セレクタを連結することはパフォーマンスを低下させるようです。 (普通に考えれば走査するパターン数が増えるのだと思いますが、どの程度のものか調査していません。)

代わりに、.class-a-b を設定できないか検討します。

命名規約

クラス名の単語はハイフン

クラス名をキャメルケース、スネークケースなどで定義することもできますが、「ハイフン-」で単語を区切って命名することが多いようです。 何れかが特別秀でているとは言い難いですが、少なくともキャメルケース className は class の指定においてはあまり見かけません。

  • class="classname"
  • class="className"
  • class="class_name"
  • class="class-name"

JavaScript の変数名として定義できない名前になるため、JavaScript の可読性維持につながるという見方があるようです。

省略形の名前

データサイズを小さくするために、できるだけ略語を使うべき、という見方があります。 私の場合はこれが果たして良いことなのか判断しかねます。

略語を使うとき、どのように略すかを検討しながらコーディングする必要がありますし、場合によってはコーディングルールを増やす必要があります。

それよりは略語を使わずに素早くコーディングするほうが良い、というコーディングルールが考えられます。 このコーディングルールなら、多くの場合に名前の重複を防ぐこともできます。

繰り返し与えられる名前のときは略語にすることで文字数を大きく削れることがあるでしょう。 ただし、改行などと同じで微々たるレベルであり、gzip(gzエンコーディング) などを行えば、実用的な十分小さいデータサイズになると思います。

参考資料

いくつかの参考資料を直接読まれる方がタメになることもあると思います。先に紹介しておきます。

GitHub's CSS PERFORMANCE - Speaker Deck

今や知らない開発者はいなくなったといえる GitHub の 2012 年の資料です。パフォーマンス調整に関する基本的な技術はすべてここに掲載されています。

Writing Efficient CSS - MDN

FireFox などを開発する MDN(mozilla) の 2000 年の資料です。かなり古いですが基本は抑えられていますし、日本語なので多少読みやすいです。

メンテナブルCSS - 株式会社 CyberAgent

株式会社 CyberAgent(著:中島幸樹 氏) の資料です。業務レベルでのテクニックも掲載されています。日本語で読みやすく、

Google HTML/CSS Style Guide

Google の HTML および CSS に関するコーディングガイドラインです。