【入門編】 ペイントフラッシングの可視化とデバッグ – Webブラウザの仕組み実践ガイド

こんにちは!フロントエンドの現場を渡り歩いてきたチーフアーキテクトの私です。

日々、モダンなWebアプリケーションを作っていると、「なんだかこの画面、スクロールするたびにカクつくな…」「ボタンを押したときに、ほんの一瞬だけ引っかかる感じがするな…」なんてモヤモヤした経験はありませんか?

コードは綺麗に書いたはずなのに、なぜかブラウザが重い。そんなとき、私たちは一体どこを見ればいいのでしょうか?

今回は、ブラウザの裏側でこっそり起きている「ペイント(再描画)」という現象にスポットライトを当てます。「なんだか難しそう…」と思うかもしれませんが、大丈夫ですよ。身近な例えを交えながら、一緒に優しく紐解いていきましょう!

—

そもそも「ペイント(再描画)」ってなに?

Webブラウザが画面を表示する仕組みを、よく「絵の具でカンバスに絵を描く作業」に例えられます。

私たちが書いたHTMLやCSSをブラウザが読み込んで、「ここに赤いボタンがあって、その上に文字があって…」と構造を理解し(DOM/CSSOMの構築)、画面というカンバスの上に実際にピクセルを描き込んでいく。これがペイント(Paint)です。

さて、ここからが本題です。
例えば、Webページをスクロールしたり、マウスをホバーして色を変えたりしたとき、ブラウザは画面全体の絵を毎回イチから描き直しているのでしょうか?

……もしそんなことをしていたら、スマホのバッテリーは一瞬で切れてしまいますし、画面はカクカクで使い物になりませんよね。

実はブラウザは賢いので、「変更があった部分(変わった場所)だけ」をピンポイントで塗り直そうとします。この、画面の一部が新しく塗り直される現象を、現場では「ペイントフラッシング(Paint Flashing)」と呼んでいます。

身近な例え:ホワイトボードの消し方

学校やオフィスの会議室にあるホワイトボードを思い浮かべてみてください。

文字を1文字だけ書き直すとき、あなたは何をしますか?
ボード全体をきれいなイレーザーで真っ白にしてから、全部の文字を書き直しますか? そんなことしませんよね。間違えた部分だけを消して、さっと書き直すはずです。

ブラウザのペイントもこれと同じです。
しかし、私たちが書いたCSSの指定がちょっぴり不親切だったりすると、ブラウザが「あれ?もしかして画面全体を消して描き直さなきゃいけないのかな…?」と勘違いしてしまい、関係ない場所まで何度もペイントしてしまう(=無駄な再描画が発生する)ことがあります。これがパフォーマンス低下の大きな原因なんです。

—

目に見えない「ペイント」を可視化してみよう

「でも、ブラウザがどこをペイントしているかなんて、目に見えないじゃないですか」
そう思いますよね。ふふふ、そこでお助けツールの登場です。

Google Chromeなどのブラウザには、ブラウザの裏側の動きを裸眼で見えるようにしてくれる魔法のような機能が備わっています。これを使って、「ブラウザが今どこを塗り直しているのか」を可視化してみましょう。

実際にデバッグ機能を覗いてみる手順

1. Chromeなどのブラウザで、重いと感じるWebページを開きます。
2. キーボードの `F12` キー(Macなら `Option + Command + I`)を押して、開発者ツール(DevTools)を開きます。
3. コマンドメニューを出します。

  • Windows: `Ctrl + Shift + P`
  • Mac: `Command + Shift + P`

4. 検索窓に 「Rendering」 と入力し、「Show Rendering(レンダリングタブを表示)」を選択します。
5. 下部(または横)に出てきた「Rendering」タブの中にある、「Paint flashing」 というチェックボックスにチェックを入れます。

さあ、どうでしょう?
その状態で、ページをスクロールしたり、マウスを動かしたりしてみてください。

……画面が緑色(または赤や青など)にチカチカと点滅しませんでしたか?

この「チカチカ」こそが、今まさにブラウザが「ここをペイントしたよ!」と教えてくれているサイン(ペイントフラッシング)です。

  • ちょっとマウスを動かしただけなのに、画面全体が緑色に激しく点滅している場合:

→ ブラウザが無駄に頑張りすぎています。「あぁ、あそこもここも塗り直さなきゃ!」とパニックになっている状態です。

  • 動かしたパーツの周りだけが、ピンポイントで優しく緑色に光る場合:

→ 素晴らしい!ブラウザは効率よく最低限の場所だけを塗り直せています。

この「チカチカ」を減らしていくことが、サクサク動くWebサイトを作るための第一歩なんです。

—

無駄なペイントを防ぐための、ほんの少しのコツ

「じゃあ、どうすればこのチカチカを減らせるの?」
安心してください。初心者の方でも今日から試せる、実用的なアプローチをひとつご紹介します。

例えば、以下のような「ふわっと動く要素(アニメーション)」があるとします。

こんにちは、ブラウザさん!

.box {
width: 200px;
height: 200px;
background-color: #ff6b6b;
/ ここで位置を変えようとしていませか? /
margin-top: 0px;
transition: margin-top 0.3s ease;
}

.box:hover {
/ marginを変えて動かすと、周囲のレイアウトも巻き込んでペイントが走りやすい /
margin-top: 20px;
}

この書き方だと、マウスを乗せたときに `margin-top` が変わるため、ブラウザは「うわっ、上のレイアウトが変わったから、周りの要素も全部計算してペイントし直さなきゃ!」と大忙しになってしまいます(Paint flashingが盛大に起きます)。

これを、ブラウザの「レイヤー(層)」の仕組みを使ってスマートに解決してみましょう。

.box {
width: 200px;
height: 200px;
background-color: #ff6b6b;
/ GPUにお願いして、この要素を「別の透明な下敷き(レイヤー)」に切り分ける /
transform: translateZ(0);
transition: transform 0.3s ease;
}

.box:hover {
/ レイアウトを変えずに、場所(transform)だけを動かす /
transform: translateY(20px);
}

`transform` や `opacity` といったプロパティを使ってアニメーションさせると、ブラウザは親分(メインの画面)に迷惑をかけず、その要素単体の「独立した下敷き」の上だけで動いてくれます。
結果として、Paint flashingのチカチカ範囲が劇的に狭くなり、画面がフリーズするようなカクつきが嘘のように消えていくんです。

—

最後に:完璧を目指さなくて大丈夫

Webブラウザの仕組みやレンダリングの世界は、奥が深くて最初は圧倒されてしまうかもしれません。「どのプロパティがペイントを引き起こすんだっけ…」と悩むこともあるでしょう。

でも、安心してください。
まずは今日覚えた `Paint flashing` のチェックを入れて画面をチカチカさせてみる。それだけで、あなたはもう「ブラウザの裏側の動きが見えるエンジニア」の一歩を踏み出しています。

「あ、ここが無駄に光ってるな。ちょっと書き方を変えてみようかな」
そんなふうに、ブラウザと対話しながら開発を楽しめるようになると、フロントエンドの世界がもっともっと好きになりますよ。

それでは、あなたのWeb制作が快適でワクワクするものになりますように。チーフアーキテクトの私でした!

コメント

タイトルとURLをコピーしました