web-dev-qa-db-ja.com

どのCSSセレクターまたはルールが実際のフロントエンドレイアウト/レンダリングパフォーマンスに大きな影響を与える可能性がありますか?

CSSレンダリングのパフォーマンスについて心配する価値はありますか?または、CSSの効率についてまったく心配せず、代わりにエレガントまたは保守可能なCSSの作成に集中する必要がありますか?

この質問は、CSSのどの部分が実際にデバイスのパフォーマンスに大きな影響を与える可能性があり、どのデバイス/ブラウザーまたはエンジンが影響を受ける可能性があるかについて、フロントエンド開発者にとって役立つリソースとなることを目的としています。これはではなくエレガントまたは保守可能なCSSの記述方法に関する質問であり、純粋にパフォーマンスに関するものです(ただし、ここに記述されている内容がベストプラクティスに関するより一般的な記事に役立つことを願っています)。

既存の証拠

Google および Mozilla 効率的なCSSの作成に関するガイドラインを作成し、 CSSLintの一連のルール には次のものが含まれます。

正規表現のように見えるセレクターを避けてください..パフォーマンスの低下を避けるために複雑な等式演算子を使用しないでください

しかし、それらのどれも、これらが与える影響の証拠(私が見つけることができた)を提供していません。

効率的なCSSに関するcss-tricks.comの記事 (効率のベストプラクティスの負荷を概説した後)not .. sacrifice semantics or maintainability for efficient CSS 最近。

完璧はブログ投稿を殺しますborder-radiusおよびbox-shadow単純なCSSルールよりも桁違いに遅くなりました。これはOperaのエンジンでは非常に重要でしたが、Webkitでは重要ではありませんでした。さらに、 スマッシングマガジンCSSベンチマーク は、CSS3表示ルールのレンダリング時間は重要ではなく、画像を使用して同等の効果をレンダリングするよりも大幅に高速であることがわかりました。

あなたの携帯電話を知っている さまざまなモバイルブラウザをテストした そしてそれらはすべてCSS3を同じようにわずかに速く(12msで)レンダリングしたが、PCでテストを行ったように見えるので、どのように手であるかについては何も推測できません-保持されているデバイスは、一般的にCSS3で動作します。

効率的なCSSの書き方については、インターネット上に aremanyarticles があります。ただし、CSSが不適切に考慮されていることが実際にサイトのレンダリング時間またはスナップ性に重要な影響を与えるという包括的な証拠はまだ見つかりません。

バックグラウンド

私はこの質問に報奨金を提供し、SOのコミュニティの力を利用して、十分に研究された有用なリソースを作成しようとしました。

54
Robin Winslow

ここで最初に頭に浮かぶのは、 レンダリングエンジン を使用していることはどれほど賢いのかということです。

それは、一般的に聞こえますが、CSSのレンダリング/選択の効率を疑問視するときに非常に重要です。たとえば、CSSファイルの最初のルールが次のとおりであるとします。

_.class1 {
    /*make elements with "class1" look fancy*/
}
_

したがって、非常に基本的なエンジンがそれを検出すると(これが最初のルールであるため)、DOM内のすべての要素を調べて、それぞれに_class1_が存在するかどうかを確認します。より優れたエンジンは、おそらくクラス名をDOM要素のリストにマップし、効率的なルックアップのためにハッシュテーブルのようなものを使用します。

_.class1.class2 {
    /*make elements with both "class1" and "class2" look extra fancy*/
}
_

この例の「基本エンジン」は、DOMの各要素に行き、両方のクラスを探します。賢いエンジンはn('class1')n('class2')を比較します。ここで、n(str)はクラスstrとのDOM内の要素の数であり、最小のものを取ります。それが_class1_であるとすると、_class1_を持つすべての要素を渡し、_class2_を持つ要素も探します。

いずれにせよ、最新のエンジンは賢く(上記の例よりもはるかに賢い)、光沢のある新しいプロセッサは1秒間に数百万(数千万)の操作を実行できます。 DOMに数百万の要素がある可能性は非常に低いため、選択(O(n))の最悪の場合のパフォーマンスはとにかく悪くはありません。


更新:

Facebook:〜1900要素(私の個人的なメインページでテスト済み)。
Google:〜340要素(メインページでテスト済み、検索結果なし)。
Google:〜950要素(検索結果ページでテスト済み)。
Yahoo!:〜1400要素(メインページでテスト済み)。
Stackoverflow:〜680要素(質問ページでテスト済み)。
AOL:〜1060要素(メインページでテスト済み)。
ウィキペディア:〜6000要素、そのうち2420はspansまたはanchors(テスト済み)ではありません グリーに関するウィキペディアの記事 )。
Twitter:〜270要素(メインページでテスト済み)。

これらを合計すると、平均で約1500個の要素が得られます。それでは、いくつかのテストを行います。テストごとに、1500 divs(一部のテストでは他のdivs内にネストされています)を生成しました。それぞれのテストに応じて適切な属性があります。


テスト

スタイルと要素はすべてPHPを使用して生成されます。使用したPHPをアップロードし、インデックスを作成して、他の人がローカルでテストできるようにしました: 小さなリンク


結果:

各テストは3つのブラウザで5回実行されます(平均時間が報告されます):Firefox 15.0(A)、 Chrome 19.0.1084.1(B)、Internet Explorer 8(C):

_                                                                        A      B      C
1500 class selectors (.classname)                                      35ms   100ms  35ms
1500 class selectors, more specific (div.classname)                    36ms   110ms  37ms
1500 class selectors, even more specific (div div.classname)           40ms   115ms  40ms
1500 id selectors (#id)                                                35ms   99ms   35ms
1500 id selectors, more specific (div#id)                              35ms   105ms  38ms
1500 id selectors, even more specific (div div#id)                     40ms   110ms  39ms
1500 class selectors, with attribute (.class[title="ttl"])             45ms   400ms  2000ms
1500 class selectors, more complex attribute (.class[title~="ttl"])    45ms   1050ms 2200ms
_

同様の実験:

どうやら他の人が同様の実験を行ったようです。これにもいくつかの有用な統計があります: 小さなリンク


結論:

チャットページを作成していて、すべてのメッセージのスタイルを設定するとします。各メッセージは、divを持つtitleにあり、クラス_.chatpage_でdiv内にネストされていることがわかります。 _.chatpage div[title]_を使用してメッセージを選択するのは正しいですが、効率的にも悪い習慣です。すべてのメッセージにクラスを与え、そのクラスを使用してそれらを選択する方が、より簡単で、保守しやすく、より効率的です。


派手なワンライナーの結論:

「ええ、このCSSは理にかなっています」の範囲内にあるものはすべて大丈夫です。

48
Chris

ここでのほとんどの回答は、セレクターのパフォーマンスに焦点を当てています。私はいくつかのスピリットトリビア(ネタバレ注意:それらは常に良い考えではない)、cssは値のパフォーマンスと特定のプロパティのレンダリングをカバーしようとします。

答えを得る前に、IMOを邪魔にならないようにしましょう:個人的には、「証拠に基づくデータ」の必要性に強く反対します。それは単にパフォーマンスの主張が信頼できるように見える一方で、実際にはレンダリングエンジンの分野は、そのような統計的結論を測定するには不正確にし、採用または監視するのは非現実的であるほど異質です。

元の調査結果がすぐに時代遅れになるので、フロントエンドの開発者が基本原則と保守性/可読性のブラウニーポイントに対する相対的な価値を理解していることを望んでいます-結局のところ、時期尚早の最適化がすべての根源です悪の ;)


セレクターのパフォーマンスから始めましょう。

浅い、できれば1レベルの特定のセレクターがより高速に処理されます。 明示的なパフォーマンスメトリックが元の回答から欠落していますが、重要な点は残っています。実行時にHTMLドキュメントが解析されます。平均深度ND要素を含み、合計SCSSルールが適用されているDOMツリー。計算の複雑さを下げるにはO(N*D*S)

  1. 右端のキーをできるだけ少ない要素に一致させる-セレクターは右から左に一致します ^ 個々のルールの適格性のために、右端のキーが一致しない場合特定の要素の場合、セレクターをさらに処理する必要はなく、破棄されます。

    *セレクターは避けるべきであると一般に認められていますが、この点についてはさらに理解する必要があります。 「通常の」CSSリセットは、実際、ほとんどの要素に一致します-このSOページがプロファイルされている場合、リセットはすべてのセレクター一致時間の約3分の1を担当するため、お勧めします- normalize.cssそれでも、合計すると.5ms-時期尚早の最適化に対するポイントは強力です

  2. 子孫セレクターを避ける最大~D要素を繰り返す必要があるため。これは主に不一致の確認に影響します。たとえば、正の.container .content一致は、親子関係の要素に対して1つのステップしか必要としない場合がありますが、DOMツリーはhtmlまでトラバースする必要があります。ネガティブマッチが確認される前に。

  3. DOM要素の数を最小限に抑えるスタイルが個別に適用されるため(注目に値します。これは、参照キャッシュや同一要素からのスタイルのリサイクルなどのブラウザロジックによって相殺されます-たとえば、同一の兄弟をスタイリングする場合

  4. 未使用のルールを削除ブラウザは、レンダリングされたすべての要素に対する適用性を評価する必要があるためです。十分に言った-最速のルールはそこにないものです:)

これらは、レンダリングエンジンのパフォーマンスの観点から定量化可能な(ただし、ページによっては必ずしも認識できるとは限らない)改善をもたらしますが、トラフィックのオーバーヘッドやDOM解析などの追加の要因が常にあります。


次に、CSS3プロパティのパフォーマンス:

CSS3は、(とりわけ)丸みを帯びた角、背景のグラデーション、ドロップシャドウのバリエーションをもたらしました。そして、それらとともに、トラック一杯の問題が発生しました。考えてみてください。定義上事前にレンダリングされた画像は、最初にレンダリングする必要のあるCSS3ルールのセットよりもパフォーマンスが優れています。から webkit wiki

CSSのグラデーション、影、その他の装飾は、必要な場合にのみ使用する必要があります(たとえば、コンテンツに基づいて形状が動的である場合)。それ以外の場合、静止画像は常に高速です。

それが十分に悪くない場合は、すべての再ペイント/リフローイベントでグラデーションなどを再計算する必要がある場合があります(詳細は以下を参照)。大多数のユーザーが閲覧できるようになるまで、これを覚えておいてください このようなcss3-重いページ 目立った遅れはありません。


次に、スピリットパフォーマンス:

トラフィックのフットプリントが比較的小さい場合でも、背が高く幅の広いスプライトは避けてください。レンダリングエンジンはgif/jpg/pngで動作できず、実行時にすべてのグラフィカルアセットが非圧縮ビットマップとして操作されることはよく忘れられています。少なくとも計算は簡単です。 このスプライト の幅×高さ×4バイト/ピクセル(RGBA)は238*1073*4≅1MBです。同時に開いているさまざまなタブのいくつかの要素で使用すると、すぐに大きな価値が生まれます。

それのかなり極端なケースは mozilla webdevで取り上げられました ですが、 対角スプライト のような疑わしいプラクティスが使用されている場合、これはまったく予想外ではありません。

考慮すべき代替案は、CSSに直接埋め込まれた個々のbase64エンコード画像です。


次に、リフローとリペイント:

reflow はJS DOM操作でのみトリガーできるというのは誤解です。実際、レイアウトに影響するスタイルを適用すると、ターゲット要素、その子、それに続く要素などに影響を与えることになります。 不必要な反復を防ぐ唯一の方法は、依存関係のレンダリングを避けるを試みることです。これの簡単な例は次のようになります レンダリングテーブル

テーブルは、要素がDOMでの前にある他の要素の表示に影響を与える可能性があるまれなケースのひとつであるため、レイアウトが完全に確立される前に複数のパスを必要とすることがよくあります。テーブルの最後にある非常に幅の広いコンテンツのセルを想像してみてください。これにより、列のサイズが完全に変更されます。これが、すべてのブラウザでテーブルが段階的にレンダリングされない理由です。


見逃した重要なことを思い出したら、編集します。終了するいくつかのリンク:

http://perfectionkills.com/profiling-css-for-fun-and-profit-optimization-notes/

http://jacwright.com/476/runtime-performance-with-css3-vs-images/

https://developers.google.com/speed/docs/best-practices/payload

https://trac.webkit.org/wiki/QtWebKitGraphics

https://blog.mozilla.org/webdev/2009/06/22/use-sprites-wisely/

http://dev.opera.com/articles/view/efficient-javascript/

11
o.v.

そのような大きな報奨金については、私はヌルの答えを危険にさらすことをいとわない:レンダリングでかなりの速度低下を引き起こす公式のCSSセレクターはなく、(高速コンピューターと高速ブラウザー反復の今日では)見つかったものはすぐに見つかりますブラウザメーカーによって解決されました。不注意な開発者が非標準のjQueryセレクターを使用する意思がない限り、モバイルブラウザーでも問題はありません。これらはjQuery開発者によって危険であるとマークされており、実際に問題になる可能性があります。

この場合、証拠の欠如は問題の欠如の証拠です。したがって、セマンティックマークアップ(特にOOCSS)を使用し、あいまいなブラウザーで標準のCSSセレクターを使用したときに見つかった速度低下を報告します。

未来の人々:2012年のCSSパフォーマンスの問題はすでに過去のものでした。

4
alexfernandez

それは本当ですが

コンピューターは10年前はずっと遅かった。

また、最近では、Webサイトにアクセスできるさまざまなデバイスがあります。デスクトップ/ラップトップは飛躍的に進歩しましたが、ミッドエンドおよびローエンドのスマートフォン市場のデバイスは、多くの場合、10年前のデスクトップよりもはるかに強力ではありません。

しかし、CSSの選択速度は、可能な限り広いデバイス範囲に優れたエクスペリエンスを提供するという点で、おそらく心配する必要のあるリストの一番下に近いと言っています。

これを拡張すると、非効率的なCSSセレクターで苦労している最新のブラウザーやモバイルデバイスに関連する特定の情報を見つけることができませんでしたが、次のことを見つけることができました。

  1. http://www.stevesouders.com/blog/2009/03/10/performance-impact-of-css-selectors/

    かなり古い(IE8、Chrome 2)ですが、一部のブラウザーでさまざまなセレクターの効率を確立するための適切な試みがあり、CSSルールの数がページのレンダリング時間にどのように影響するかを定量化しようとしています。

  2. http://www.thebrightlines.com/2010/07/28/css-performance-who-cares/

    再びかなり古い(IE8、Chrome 6))が、非効率的なCSSセレクターで極端になります* * * * * * * * * { background: #ff1; }パフォーマンスの低下を確立します。

4
Simon West

それを速くするための無関係な方法ではありません。パフォーマンスを見るとき、それはあなたが最後に見るものでなければなりません。自分に合った方法でCSSを作成し、コンパイルします。そしてそれを頭に入れます。これは大雑把かもしれませんが、ブラウザのパフォーマンスを調べるときに探すべき他のことがたくさんあります。あなたがデジタルビューローで働いているなら、あなたはロード時間でその余分な1msをするために支払われることはありません。

私がコメントしたようにchromeのためにpagespeedを使用してください27のパラメータでウェブサイトを分析するそのグーグルツールcssはそれらの1つです。

私の投稿は正確に関係しているだけで、IE7などを使用している人でも、約99%のWebユーザーがWebサイトを開いて正しく表示できるようにすることはできません。 css3を使用して 10% で終了するよりも、(パフォーマンスが1〜10ミリ秒余分に得られることが判明した場合)。

ほとんどの人は少なくとも1mbit/512kbit以上を持っており、重いサイトをロードする場合、ロードするのに約3秒かかりますが、おそらくcssで10ms節約できますか?

また、モバイルデバイスに関しては、モバイル専用のサイトを作成する必要があるため、画面サイズが「幅」ピクセル未満のデバイスの場合は、別のサイトがあります。

以下にコメントしてください。これは私の見解であり、Web開発に関する私の個人的な経験です。

1
Simon Dragsbæk

コードに直接関連するわけではありませんが、<link>ではなく@importを使用してスタイルシートを含めると、パフォーマンスが大幅に向上します。

'stevesouders.com経由で@importを使用しないでください

この記事には、各タイプ間の速度テストの例が多数含まれているほか、あるタイプと別のタイプが含まれています(例:<link>を介して呼び出されるCSSファイルには別のcssファイルへの@importも含まれています)。

0
justacoder