Tags:, Posted in Web Leave a Comment

painterGoogle Page Speedの記事から始まってしまったサイト高速化関連記事。
今回は、効率の良いスタイルを書くために、ブラウザがHTMLを解析してDOMツリーをつくり、そこにスタイルをあてていく過程を見ていきましょう。

基本的な手順がわかると、どういったcssの書き方が効率が良く、どういった書き方では迂遠であったり冗長であったりするのかが、理解できるようになると思います。

この記事は、Google Page Speedの”“および、Mozillaの”Writing Efficient CSS for use in the Mozilla UI“などを元に書いています。そのため、この仕組みは主にMozillaエンジンについてです。IEやWebKitでは若干異なった動作をする部分もあるようです。

マッチングの回数

ブラウザは、読み込んだHTMLをパースしてDOMツリーを作成します。
その後、ツリーを辿りながらそれぞれの要素について、各スタイルが合致するかどうかを検証することになります。検証はルールのグルーピング(後述)などにより効率化はされていますが、基本的には全ての要素を駆動表に、全てのスタイルルールを検証する作業になります。つまり、端的には次のような計算数分だけ、マッチングが行われるわけです。

HTML中の全要素数 × スタイル上のルール数

例えば、次のようなシンプルな文書があったとします。


  


  

タイトル

...
...

この中に、要素は5つ(body, h1, div x 3)あります。スタイルは3つです。5つの各要素に対して3つのルールがマッチするかを検証するわけですから、マッチング数としては 5 x 3 となり、計15回のマッチングが行われる計算になります。

マッチングの詳細

では、今度は各マッチングを見ていきます。
まず”Keyセレクタ”という言葉を覚えてください。これは、単純に「ルールの一番右側にあるセレクタ」を指します。例えば次のようなスタイルがあった場合、

  #id { ... }
  .class div, .class p { ... }
  div.class form input[checked="checked"] { ... }

Keyセレクタは上から順に、#id、divとp、input[checked="checked"]です。
このKeyセレクタが次のいずれに該当するかで、スタイルルールをまず大きく4つに分類します。

  • ID Rules
    KeyセレクタがIDであるもの。

    button#backButton { }
    #urlBar[type="autocomplete"] { }
    treeitem > treerow > treecell#myCell:active { }
    
  • Class Rules
    Keyセレクタがクラス指定であるもの。

    button.toolbarButton { }
    .fancyText { }
    menuitem > .menu-left[checked="true"] { }
    
  • Tag Rules
    Keyセレクタがタグ指定であるもの。

    td { }
    treeitem > treerow { }
    input[type="checkbox"] { }
    
  • Universal Rules
    Keyセレクタが、つまり上記3つのいずれにも当てはまらないもの。

    [hidden="true"] { }
    * { }
    tree > [collapsed="true"] { }
    

このようなグループ分けをした上で、マッチングは該当要素に合致するかどうかを、ルールの右(Keyセレクタ)から順に左方向に確認していきます。合致しなくなったところで検証を止めます。

具体的に見てみましょう。
次のようなスタイルがあったとします。

div.cls fieldset > input { ... }

HTMLは、次のようにします。


  

ここで6行目のcheckboxを、前述のスタイルルールにマッチングしてみます。

  1. Keyセレクタである”input”がタグなので、このルールはTag Rulesに分類されています。この要素はまずTag Rules中のinputにマッチするかを確認し、検証を始めます。
  2. ひとつ左に行くと、これは「1つ親の要素がfieldsetである」という意味です。そこでDOMツリーでひとつ上を確認(5行目)すると、確かにfieldsetです。
  3. そこで次のルールを確認します。次は「先祖にclsという名前のクラスを持つdiv要素があること」です。DOMツリーを順に辿っていくと(4→3→2行目)、該当するものが見つかりました。
  4. 全てのルールに合致したので、このスタイルを適用します。

では次に、次のようなルールを検証してみましょう。

#id { ... }

これは当然、ID Rulesにカテゴライズされています。

  1. idというidを持つ要素であるので、合致する

終わりです。

これは極端な例ですが、スタイル指定の効率の良し悪しが想像つくと思います。
次は、具体的に効率の悪いスタイル記述を挙げてみます。そういった記述を極力避けることで、スタイルの適用を高速化することができます。

このエントリーをはてなブックマークに追加
Bookmark this on Yahoo Bookmark
Bookmark this on Livedoor Clip
Share on FriendFeed
Share on StumbleUpon
Newsing it!

Related posts:

  1. [jQuery Mobile] ActionSheetプラグイン
  2. [Web] Google Page Speedでサイトを高速化(3)
  3. [css] 効率の良いcssを書くための7箇条

2009 年 6 月 15 日