DevTools の連続描画モードを使用した長い描画時間のプロファイリング

Chrome Canary で、ペイント プロファイリングの連続ペイント モードを利用できるようになりました。この記事では、ページの描画時間の問題を特定する方法と、この新しいツールを使用して描画パフォーマンスのボトルネックを検出する方法について説明します。

ページのペイント時間を調べる

ページがスムーズにスクロールしていないことに気づきました。問題への対処はここから始めますこの例では、Dan Cederholm によるデモページ「Things We Left On The Moon」を使用します。

ウェブ インスペクタを開き、タイムラインの記録を開始し、ページを上または下にスクロールします。次に、縦方向のタイムラインを見て、各フレームで何が起こったかを確認します。

タイムライン記録のスクリーンショット

ほとんどの時間がペイントに費やされていることがわかった場合(60 fps を超える大きな緑色のバー)、その原因を詳しく調べる必要があります。ペイントを調査するには、Web Inspector の [Show paint のデフォルト] 設定(Web Inspector の右下隅にある歯車アイコン)を使用します。ペイントされるリージョンが表示されます

タイムラインの描画にかかった時間のスクリーンショット

Chrome でページの領域が再描画される理由はいくつかあります。

  • JavaScript で DOM ノードが変更されると、Chrome でページのレイアウトが再計算されます。
  • 再生中のアニメーションは、フレームベースのサイクルで更新されます。
  • マウスオーバーなどのユーザー操作により、特定の要素のスタイルが変更されます。
  • ページ レイアウトを変更するその他の操作。

デベロッパーは、ページで発生する再ペイントに注意する必要があります。そのためには、ペイントする長方形を確認することをおすすめします。上記のスクリーンショットの例では、画面全体が大きな長方形のペイントで覆われています。つまり、スクロールすると画面全体が再ペイントされるため、これは好ましくありません。このケースでは、CSS スタイル background-attachment:fixed が原因でこの問題が発生します。スクロールすると、ページの背景画像は同じ位置に留まりますが、ページのコンテンツはその上に移動します。

再ペイントで広い領域をカバーしていることや、時間がかかることが判明した場合は、次の 2 つの方法があります。

  1. ページ レイアウトを変更して、描画を減らすこともできます。可能な場合、Chrome は表示ページを 1 回だけペイントし、下にスクロールしたときに表示されない部分を追加します。ただし、場合によっては、特定の領域を再描画する必要があります。たとえば、同じ位置に留まるナビゲーション要素によく使用される CSS ルール position:fixed によって、このような再描画が行われることがあります。
  2. ページ レイアウトを維持したい場合は、再描画される領域の描画コストを削減してみます。描画コストは CSS スタイルによって異なり、ほとんど影響しないものもあれば、大きいものもあります。特定のスタイルの描画コストを把握するには、大変な作業です。これを行うには、[要素] パネルでスタイルを切り替え、タイムラインの記録の違い(パネルを切り替えて多数の記録を行う)を確認します。このような場合に役立つのが、連続ペイント モードです。

連続描画モード

連続描画モードは、ページ上で負荷の高い要素を特定するためのツールです。ページを常に再描画状態にし、描画処理が行われている時間を示すカウンタを表示します。次に、要素を非表示にしてスタイルを変更し、カウンタを監視して、何が遅いかを調べます。

セットアップ

連続ペイント モードを使用するには、Chrome Canary を使用する必要があります。

Linux システム(および一部の Mac)では、Chrome が合成モードで実行されるようにする必要があります。これは、about:flags の [すべてのページでの GPU 合成] の設定を使用して永続的に有効にできます。

開始方法

連続ペイント モードは、Web Inspector の設定にある [EnableContinuous page repainting] チェックボックス(Web Inspector の右下隅にある歯車アイコン)で有効にできます。

連続描画モード

右上の小さなディスプレイに、測定されたペイント時間がミリ秒単位で表示されます。具体的には、次のことがわかります。

  • 左側は、最後に測定されたペイント時間です。
  • 右側の現在のグラフの最小値と最大値。
  • 下のバーには、過去 80 フレームの履歴が表示されている棒グラフ(グラフの線は基準点として 16 ミリ秒を示しています)。

ペイント時間の測定値は、画面の解像度、ウィンドウ サイズ、Chrome が実行されているハードウェアによって異なります。これらはユーザーによって異なる可能性があります。

ワークフロー

このように、継続的ペイント モードを使用して、ペイントのコストを増大させる要素とスタイルを突き止めることができます。

  1. ウェブ インスペクタの設定を開き、[継続的なページの再描画を有効にする] をオンにします。
  2. [要素] パネルに移動し、矢印キーで DOM ツリーをトラバースするか、ページ上の要素を選択します。
  3. 要素の表示を切り替えるには、新たに導入されたヘルパーである H キーボード ショートカットを使用します。
  4. ペイント時間のグラフを見て、ペイント時間を長くしている要素を見つけます。
  5. その要素の CSS スタイルを確認し、グラフを見ながらオンとオフを切り替えて、速度低下の原因となっているスタイルを見つけます。
  6. このスタイルを変更してもう一度タイムライン記録を行い、ページのパフォーマンスが向上したかどうかを確認してください。

以下のアニメーションは、スタイルの切り替えとペイント時間への影響を示しています。

ContinuousPaint のスクリーンキャスト

この例では、CSS スタイルの box-shadow または border-radius をオフにすることで、描画時間が大幅に短縮される様子を示しています。1 つの要素に box-shadowborder-radius の両方を使用すると、Chrome ではこれを最適化できないため、ペイント オペレーションのコストが非常に高くなります。そのため、この例のように何度も再ペイントを行う要素がある場合は、この組み合わせを避ける必要があります。

メモ

連続描画モードでは、表示ページ全体が再描画されます。ウェブページを閲覧しているときは、通常このようなことは起こりません。通常、スクロールで描画されるのは、これまで表示されていない部分のみです。ページ上の他の変更については、可能な限り狭い領域のみが再描画されます。そのため、別のタイムライン記録で、スタイルの改善が実際にページのペイント時間に影響を与えたかどうかを確認してください。

continuous painting mode を使用する際、たとえば CSS スタイル border-radiusbox-shadow では、描画に多くの時間がかかることがわかります。これらの機能の使用は一般的におすすめしません。これらの機能は素晴らしいものであり、ついに実現できたことを嬉しく思います。ただし、いつ、どこで使うかを知っておくことが重要です。再ペイントの多い場所では使用を避け、通常は使いすぎないようにします。

ライブデモ

以下をクリックすると、Paul Irish が連続塗装を使用して、独特の高価な塗装作業を特定するデモが表示されます。