ペイントの複雑さの簡素化とペイントエリアの削減

ペイントとは、最終的にユーザーの画面に合成されるピクセルを書き込む処理です。これは多くの場合、パイプライン内のすべてのタスクの中で最長実行時間であり、可能な限り避ける必要があります。

ペイントは、最終的にユーザーの画面に合成されるピクセルを書き込む処理です。多くの場合、これはパイプライン内のすべてのタスクの中で最も長時間実行されるため、可能な限り避ける必要があります。

まとめ

  • 変換または不透明度以外のプロパティを変更すると、常にペイントがトリガーされます。
  • ペイントは多くの場合、ピクセル パイプラインで最も高価な部分であるため、できる限り避けてください。
  • レイヤ プロモーションとアニメーションのオーケストレーションにより、ペイントエリアを縮小します。
  • Chrome DevTools のペイント プロファイラを使用して、ペイントの複雑さとコストを評価し、可能な部分を減らします。

レイアウトとペイントのトリガー

レイアウトをトリガーすると、常にペイントがトリガーされます。要素のジオメトリを変更すると、要素のピクセルを修正する必要があるためです。

フルピクセル パイプライン。

また、背景、テキストの色、シャドウなど、ジオメトリ以外のプロパティを変更した場合にも、ペイントをトリガーできます。その場合、レイアウトは必要なく、パイプラインは次のようになります。

レイアウトなしのピクセル パイプライン。

Chrome DevTools を使用して塗装のボトルネックをすばやく特定する

Chrome DevTools を使用して、ペイントされている領域をすばやく特定できます。[レンダリング] タブを開き、[ペイント フラッシュ] を有効にします。

Chrome でこのオプションを有効にすると、ペイントが行われるたびに画面が緑色で点滅します。画面全体が緑色で点滅している場合や、画面上でペイントすべきではないと思う領域がある場合は、もう少し詳しく調べる必要があります。

ペイントが行われるたびに、ページが緑色で点滅します。

移動またはフェードする要素をプロモートする

ペイントは、必ずしもメモリ内の単一の画像に行われるわけではありません。実際、ブラウザは必要に応じて複数の画像やコンポジタ レイヤにペイントできます。

コンポジタ レイヤの表現。

このアプローチの利点は、定期的に再ペイントされる要素や、変換によって画面上を移動する要素を、他の要素に影響を与えずに処理できることです。これは、個々のレイヤを処理して合成し、最終的な画像を作成できる Sketch、GIMP、Photoshop などのアート パッケージと同じです。

新しいレイヤを作成する場合、CSS プロパティ will-change を使用することをおすすめします。これは Chrome、Opera、Firefox で機能し、値を transform にすると新しいコンポジタ レイヤが作成されます。

.moving-element {
  will-change: transform;
}

will-change には対応していないものの、レイヤの作成に対応しているブラウザ(Safari や Mobile Safari など)では、3D 変換を(誤って)使用して新しいレイヤを強制的に作成する必要があります。

.moving-element {
  transform: translateZ(0);
}

ただし、各レイヤはメモリと管理の両方を必要とするため、あまり多くのレイヤを作成しないように注意する必要があります。これについて詳しくは、コンポジター専用プロパティに固定し、レイヤ数を管理するをご覧ください。

要素を新しいレイヤにプロモートした場合は、DevTools を使用して、パフォーマンス上のメリットがあることを確認します。プロファイリングなしで要素をプロモートしないでください。

ペイントエリアを縮小する

ただし、要素を昇格させたにもかかわらず、ペイント作業が必要になることもあります。ペイントに関する問題の大きな課題は、ペイントが必要な 2 つの領域がブラウザによって結合され、その結果として画面全体が再ペイントされる可能性があることです。たとえば、ページの一番上に固定されたヘッダーがあり、画面の下部に何かがペイントされている場合、最終的に画面全体が再ペイントされる可能性があります。

ペイント エリアを減らすには、多くの場合、アニメーションと遷移をオーケストレートして重なりすぎないようにしたり、ページの特定の部分がアニメーション化されないようにする方法を見つけたりします。

ペイントの複雑さの簡素化

画面の一部をペイントするのにかかる時間。

ペイントに関しては、ある物事が他の物よりも高価です。たとえば、ぼかしを含むもの(たとえばシャドウ)は、赤いボックスを描画するよりもペイントに時間がかかります。ただし、CSS に関しては、必ずしも明らかではありません。background: red;box-shadow: 0, 4px, 4px, rgba(0,0,0,0.5); は、必ずしもパフォーマンス特性が大きく異なるように見えますが、実際には大きく異なります。

上記のペイント プロファイラを使用すると、効果を得るために他の方法を検討する必要があるかどうかを判断できます。最終結果を得るために、より安価なスタイルのセットや別の手段を使用できるかどうか、自問してください。

特にアニメーション中は、常にペイントを避ける必要があります。特にモバイル デバイスでは、フレームあたりの 10 ms は通常、ペイント処理に十分ではないためです。