ペイントは、最終的にユーザーの画面に合成されるピクセルを塗りつぶすプロセスです。多くの場合、パイプライン内のすべてのタスクの中で最も実行時間が長く、可能な限り回避すべきタスクです。
概要
- 変換や不透明度以外のプロパティを変更すると、常にペイントがトリガーされます。
- ペイントは、多くの場合、ピクセル パイプラインで最もコストがかかる部分です。可能であれば、使用しないでください。
- レイヤのプロモーションとアニメーションのオケストレーションにより、ペイント領域を減らす。
- Chrome DevTools のペイント プロファイラを使用して、ペイントの複雑さとコストを評価し、可能な限り削減します。
レイアウトとペイントがトリガーされる仕組み
レイアウトをトリガーすると、要素のジオメトリを変更するため、ピクセルを修正する必要があるため、常にペイントがトリガーされます。

背景、テキストの色、シャドウなど、幾何学的でないプロパティを変更した場合も、ペイントをトリガーできます。この場合、レイアウトは不要で、パイプラインは次のようになります。

Chrome DevTools を使用してペイントのボトルネックをすばやく特定する
Chrome DevTools を使用すると、ペイントされている領域をすばやく特定できます。[レンダリング] タブを開き、[ペイントのフラッシュ] を有効にします。
このオプションを有効にすると、ペイントが行われるたびに画面が緑色で点滅します。画面全体が緑色で点滅している場合や、描画すべきではない画面領域が点滅している場合は、もう少し詳しく調べる必要があります。

移動またはフェードする要素を促進する
ペイントは、メモリ内の単一の画像に行われるわけではありません。実際、ブラウザは必要に応じて複数の画像またはコンポジタ レイヤにペイントできます。

このアプローチの利点は、定期的に再描画される要素や、変換によって画面上で移動する要素を、他の要素に影響を与えることなく処理できることです。これは、Sketch、GIMP、Photoshop などのアート パッケージと同じです。個々のレイヤを処理して重ね合わせ、最終的な画像を作成できます。
新しいレイヤを作成する最善の方法は、すべての主要な最新ブラウザ エンジンで利用可能な will-change
CSS プロパティを使用することです。transform
の値を使用して、will-change
は新しいコンポジタ レイヤを作成します。
.moving-element {
will-change: transform;
}
ただし、各レイヤにはメモリと管理の両方が必要になるため、レイヤを作成しすぎないように注意する必要があります。詳細については、コンポーザタ専用のプロパティに固執し、レイヤ数を管理するをご覧ください。
要素を新しいレイヤに昇格させた場合は、DevTools を使用して、パフォーマンスが向上したことを確認します。プロファイリングなしで要素を昇格させないでください。
ペイント領域を減らす
ただし、要素を昇格しても塗装作業が必要になる場合があります。ペイントの問題の大きな課題は、ブラウザがペイントが必要な 2 つの領域を結合し、画面全体が再ペイントされる可能性があることです。たとえば、ページの上部に固定ヘッダーがあり、画面の下部に何かがペイントされている場合、画面全体が再ペイントされる可能性があります。
ペイント領域を減らすには、アニメーションと遷移を調整して重複を減らすか、ページの特定の部分をアニメーション化しない方法を見つけることがよくあります。
ペイントの複雑さを簡素化

塗装には、費用のかかるものもあれば、そうでないものもあります。たとえば、ぼかし(影など)が含まれるオブジェクトは、赤いボックスを描画するよりもペイントに時間がかかります。ただし、CSS では必ずしも明らかではありません。background: red;
と box-shadow: 0, 4px, 4px, rgba(0,0,0,0.5);
はパフォーマンス特性が大きく異なるようには見えませんが、実際には異なります。
上のスクリーンショットに示すように、ペイント プロファイラを使用すると、効果を実現するための他の方法を検討する必要があるかどうかを判断できます。より安価なスタイルセットや代替手段を使用して最終的な結果を得ることは可能かどうかを自問します。
特にアニメーション中は、可能な限りペイントを避ける必要があります。通常、フレームあたりの10 ミリ秒では、特にモバイル デバイスでペイント処理を完了するのに十分な時間がありません。