ペイントは、最終的にユーザーの画面に合成されるピクセルを書き込む処理です。通常、ペイントはパイプライン内のすべてのタスクの中で最も実行時間が長いため、できるだけ避ける必要があります。
概要
- 形状または不透明度以外の任意のプロパティを変更すると、常にペイントがトリガーされます。
- ペイントは多くの場合、ピクセル パイプラインの中で最も高コストの部分です。可能であれば、使用しないでください。
- レイヤー プロモーションやアニメーションのオーケストレーションを介してペイントエリアを縮小します。
- Chrome DevTools のペイント プロファイラを使用して、ペイントの複雑さとコストを評価し、可能なものを削減します。
レイアウトとペイントがトリガーされる仕組み
要素のジオメトリを変更すると、そのピクセルの修正が必要になるため、レイアウトをトリガーすると、常にペイントがトリガーされます。
背景、テキスト色、影などの非形状プロパティを変更した場合も、ペイントをトリガーすることができます。このような場合、レイアウトは必要とされず、パイプラインは次のようになります。
Chrome DevTools を使用して、ペイントのボトルネックを迅速に識別する
Chrome DevTools を使用して、ペイントされた領域を迅速に識別することができます。[レンダリング] タブを開き、[ペイントのフラッシュ] を有効にします。
このオプションを有効にすると、ペイントが発生するたびに画面が緑色で点滅します。画面全体が緑色で点滅している場合や、塗装されるはずのない領域が画面に表示されている場合は、さらに調査を進めてください。
移動またはフェードする要素のプロモート
ペイントは、必ずしもメモリ内の単一の画像に行われるとは限りません。実際、ブラウザは複数の画像、必要な場合はコンポジ層に対してペイントを行うことができます。
このアプローチには、通常は再ペイントされる要素、または変換によって画面上を移動する要素を、他の要素に影響を与えないで処理できるという利点があります。これは Sketch、GIMP、Photoshop などのアート パッケージの手法と同じであり、個々のレイヤーを他のレイヤーに対して相互に処理および合成して最終的な画像を作成することができます。
新しいレイヤを作成する最善の方法は、すべての主要な最新ブラウザ エンジンで使用できる CSS プロパティ will-change
を使用することです。transform
の値を使用すると、will-change
は新しいコンポジ層を作成します。
.moving-element {
will-change: transform;
}
ただし、各レイヤーはメモリと管理を必要とするため、あまり多くのレイヤーを作成しないように注意する必要があります。この手法の詳細については、コンポジタ専用プロパティのみの使用、およびレイヤー数の管理 セクションを参照してください。
新しいレイヤーに要素をプロモートした場合は、それによってパフォーマンス上の利点が得られたことを DevTools によって確認してください。プロファイリングなしに要素をプロモートしないでください。
ペイントエリアを縮小する
ただし、要素をプロモートしても、ペイント作業が依然として必要になる場合があります。ペイントに関する問題の大きな課題は、ペイントが必要な 2 つの領域がブラウザによって結合され、その結果、画面全体が再ペイントされることです。したがって、たとえば、ページの最上部にヘッダーを固定し、画面の最下部に何かを描くと、最終的に画面全体が再ペイントされる可能性があります。
ペイントエリアの縮小は、通常、過度のオーバーラップが生じないようにアニメーションと遷移を調整するか、ページの特定の部分のアニメーション化を避ける方法を見つける作業です。
ペイントの複雑さの簡略化
ペイントでは、特定の処理のコストが他の処理よりも高くなります。たとえば、ブラーを必要とする処理(シャドウなど)では、赤いボックスの描画などよりもペイントに時間がかかります。ただし、CSS に関しては、これは必ずしも明白でありません。background: red;
と box-shadow: 0, 4px, 4px, rgba(0,0,0,0.5);
は、パフォーマンス特性が大きく異なるようには見えませんが、実際には異なります。
前のスクリーンショットに示すように、ペイント プロファイラでは、他の方法で効果を得る必要があるかどうかを判断できます。より低コストのスタイル、または目的の結果を実現する他の手法を使用できるかどうかを検討してください。
可能な場合は、特にアニメーションの実行中には常にペイントを避ける必要があります。特にモバイル機器上では、1 フレームあたり 10ms は、一般的にペイント作業を実行するのに十分長い時間ではありません。