SOFTELメモ Developer's blog

会社概要 ブログ 調査依頼 採用情報 ...
てるてる動画

【CSS】セレクタは右から左に解釈される?(高速化tips)

問題

CSSのセレクタは、右から左に解釈されるって本当ですか? 高速化する書き方があるとか。

答え

実装はわからないけど、仕様はそうらしい。

下表はセレクタの一覧(http://www.w3.org/TR/CSS2/selector.html#pattern-matching)。

Pattern Meaning Described in section
* Matches any element. Universal selector
E Matches any E element (i.e., an element of type E). Type selectors
E F Matches any F element that is a descendant of an E element.

「Fで Eの子孫である要素に マッチします。」

Descendant selectors
E > F Matches any F element that is a child of an element E. Child selectors
E:first-child Matches element E when E is the first child of its parent. The :first-child pseudo-class
E:link
E:visited
Matches element E if E is the source anchor of a hyperlink of which the target is not yet visited (:link) or already visited (:visited). The link pseudo-classes
E:active
E:hover
E:focus
Matches E during certain user actions. The dynamic pseudo-classes
E:lang(c) Matches element of type E if it is in (human) language c (the document language specifies how language is determined). The :lang() pseudo-class
E + F Matches any F element immediately preceded by a sibling element E. Adjacent selectors
E[foo] Matches any E element with the “foo” attribute set (whatever the value). Attribute selectors
E[foo=”warning”] Matches any E element whose “foo” attribute value is exactly equal to “warning”. Attribute selectors
E[foo~=”warning”] Matches any E element whose “foo” attribute value is a list of space-separated values, one of which is exactly equal to “warning”. Attribute selectors
E[lang|=”en”] Matches any E element whose “lang” attribute has a hyphen-separated list of values beginning (from the left) with “en”. Attribute selectors
DIV.warning Language specific. (In HTML, the same as DIV[class~=”warning”].) Class selectors
E#myid Matches any E element with ID equal to “myid”. ID selectors

高速に処理される書き方?

各ブラウザが、素直に仕様書の字句どおり実装しているのか、効率的に処理されるような何らかの工夫をした実装をしているのか、そのあたりはなんともいえないなと思ってますが、一般にはこんな感じらしいです。

左に不要なものは書かない方が速い

#A .B {/* × .Bを探して、 親に#Aがあるか探してしまう */}
.B {/* ○ .Bを探すだけ */}

一番右にマッチするものは少ない方が速い

#A * {/* ×× すべての要素について、親#Aがあるか探す */}
#A a {/* × すべてのa要素について、 親に#Aがあるか探してしまう */}
#A .B {/* ○ .Bを探して、親#Aがあるか探す */}

子孫セレクタは遅い

遅いといわれても、HTMLをコンパクトにしたいときは、よくやります。

div#A div.B ul.C li {/* × 遅い */}
.A {/* ○ 対象となる要素にclassを指定しておくのがよい */}

id、classに要素まで指定しない方が速い

要素を指定することでCSSの優先順位を上げたいときや、可読性のためには要素まで指定することもなくはない。

div#A {/* × #AでなおかつDIVである要素を探す */}
#A {/* ○ #Aを探すだけ */}

こんなこともあるんだなという程度に覚えておいて、よほどレンダリングが遅いと感じたときにでもCSSを確認するとよいでしょう。

関連するメモ

コメント