54

CSS レンダリングのパフォーマンスについて心配する価値はありますか? それとも、CSS の効率性についてまったく心配する必要はなく、代わりに洗練された保守可能な CSS を書くことに専念するべきでしょうか?

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

既存の証拠

GoogleMozillaは、効率的な CSS を記述するためのガイドラインを作成しており、CSSLint の一連のルールには次のものが含まれます。

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

しかし、それらのどれも、これらが持つ影響の証拠を (私が見つけた限り) 提供していません。

効率的な CSSに関するcss-tricks.com の記事では、(大量の効率のベスト プラクティスを概説した後) 最近はすべきだと主張していnot .. sacrifice semantics or maintainability for efficient CSSます。

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

Know your mobileがさまざまなモバイル ブラウザーをテストした結果、CSS3 のレンダリング速度はどれも同等であることがわかりました (12 ミリ秒)。全般的。

効率的な CSS の書き方については、インターネット上に多くの記事があります。 しかし、よく考えられていない CSS が実際にサイトのレンダリング時間やスナッピングに重大な影響を与えるという包括的な証拠をまだ見つけていません。

バックグラウンド

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

4

6 に答える 6

48

ここで最初に思い浮かぶのは、使用しているレンダリング エンジンはどれくらい優れているかということです。

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 の各要素を再訪して、両方のクラスを探します。より賢いエンジンは、DOM 内の要素の数n('class1')n('class2')where is を class と比較し、最小のものを取ります。それが であると仮定すると、同様に持つ要素を探してすべての要素を渡します。n(str)strclass1class1class2

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


アップデート:

実際の実用的な証明を得るために、いくつかのテストを行うことにしました。まず、実際のアプリケーションで平均的にいくつの DOM 要素が見られるかを把握するために、いくつかの人気のあるサイトの Web ページに含まれる要素の数を見てみましょう。

Facebook: ~1900 要素 (個人のメイン ページでテスト)。
Google : ~340 要素 (メイン ページでテスト、検索結果なし)。
Google: ~950 要素 (検索結果ページでテスト済み)。
ヤフー!: ~1400 要素 (メイン ページでテスト済み)。
Stackoverflow: ~680 要素 (質問ページでテスト済み)。
AOL: ~1060 要素 (メイン ページでテスト済み)。
ウィキペディア: ~6000 の要素、そのうち 2420 はspansorではない (グリーに関するウィキペディアの記事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

同様の実験:

どうやら他の人も同様の実験を行っているようです。これにはいくつかの有用な統計もあります: little link .


要点:

レンダリング時に数ミリ秒 (1 ミリ秒 = 0.001 秒) を節約することに関心がない限り、あまり考えなくてもかまいません。一方、要素の大きなサブセットを選択するために複雑なセレクターを使用しないようにすることをお勧めします。これにより、顕著な違いが生じる可能性があります (上記のテスト結果からわかるように)。すべての一般的な CSS セレクターは、最新のブラウザーではかなり高速です。

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


ファンシーなワンライナーの結論:

「ええ、この CSS は理にかなっています」の範囲内であれば何でも構いません。

于 2012-09-05T10:50:10.097 に答える
13

ここでのほとんどの回答は、セレクターのパフォーマンスだけが重要であるかのように焦点を当てています。いくつかのスプライトのトリビア (ネタバレ注意: 常に良いアイデアであるとは限りません)、css 使用値のパフォーマンス、および特定のプロパティのレンダリングについて説明します。

答えにたどり着く前に、IMO について説明させてください。個人的には、「証拠に基づくデータ」の必要性について述べられていることに強く反対します。パフォーマンスの主張信頼できるものに見えるだけですが、実際にはレンダリング エンジンの分野は異質であり、そのような統計的結論を測定するのは不正確であり、採用または監視するのは実際的ではありません。

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


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

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

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

    *セレクターは避けるべきだと一般に認められていますが、この点はさらに考慮する必要があります。実際、「通常の」CSS リセットはほとんどの要素に一致します。この SO ページがプロファイリングされる場合、リセットはすべてのセレクター マッチング時間の約 1/3 を占めるため、 normalize.cssを好むかもしれません(それでも、合計するだけです)。 3.5 ミリ秒まで-時期尚早の最適化に対するポイントは強力です)

  2. ~D要素まで反復処理する必要があるため、子孫セレクターは避けてください。これは主に不一致の確認に影響します。たとえば、肯定的な.container .content一致は親子関係の要素に対して 1 つのステップのみを必要とする場合がありますがhtml、否定的な一致を確認する前に DOM ツリーをたどる必要があります。

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

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

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


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

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

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

それでも問題ない場合は、再描画/リフロー イベントごとにグラデーションなどを再計算する必要がある場合があります (詳細は以下を参照)。大多数のユーザーがこのような css3 を多用するページを目立った遅延なしで閲覧できるようになるまで、このことを念頭に置いてください。


次に、スプ​​ライトのパフォーマンス:

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

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

別の方法として、base64 でエンコードされた個別の画像を CSS に直接埋め込むことを検討してください。


次に、リフローと再描画:

リフローが JS DOM操作によってのみトリガーされるというのは誤解です。実際、レイアウトに影響を与えるスタイルのアプリケーションは、ターゲット要素、その子、およびそれに続く要素などに影響を与えます。レンダリングの依存関係を避けるためです。これの簡単な例は、テーブルのレンダリングです:

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


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

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/effective-javascript/

于 2012-09-15T08:24:14.210 に答える
5

それは本当ですが

コンピューターは 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/

    * * * * * * * * * { background: #ff1; }これもかなり時代遅れ (IE8、Chrome 6) ですが、パフォーマンスの低下を確立するために、非効率な CSS セレクターを極端に使用しています。

于 2012-09-05T11:08:29.027 に答える
4

このような大きな賞金のために、私は Null の答えを危険にさらしても構わないと思っています: レンダリングでかなりのスローダウンを引き起こす公式の CSS セレクターはありません。ブラウザメーカーによって解決されました。不注意な開発者が非標準の jQuery セレクターを使用する意思がない限り、モバイル ブラウザーでも問題はありません。これらは jQuery 開発者によって危険であるとマークされており、実際に問題になる可能性があります。

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

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

于 2012-09-13T19:12:46.410 に答える
1

css は高速化に無関係な方法ではありません。パフォーマンスを確認するときに最後に確認する必要があります。あなたに合った方法でCSSを作成し、コンパイルします。そして頭に入れます。これは大雑把かもしれませんが、ブラウザのパフォーマンスを調べるときに他にも多くのことを確認する必要があります。デジタル ビューローで働いている場合は、1 ミリ秒の読み込み時間の追加料金を支払う必要はありません。

私がコメントしたように、クロムにpagespeedを使用します.27個のパラメーターでWebサイトを分析するGoogleツールcssはその1つです。

私の投稿は正確に懸念しているだけで、IE7などを使用している人でさえ、約99%のWebユーザーがWebサイトを開いて正しく表示できるようにすることは望ましくありません. css3 を使用して約10%をクローズするよりも (パフォーマンスが 1 ~ 10 ミリ秒向上することが判明した場合)。

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

また、モバイル デバイスに関しては、モバイル専用のサイトを作成する必要があるため、画面サイズが "Width"px 未満のデバイスを使用している場合は、別のサイトを使用します。

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

于 2012-09-11T11:19:19.167 に答える
0

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

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

この記事には、各タイプ間の多数の速度テストの例が含まれており、あるタイプと別のタイプが含まれています (例: via と呼ばれる CSS ファイルには、別の css ファイル<link>も含まれます)。@import

于 2012-09-14T13:38:28.533 に答える