画面が描かれるのは魔法ではない
フロントエンド開発(Vue.js)を初めて始めたとき、私はブラウザをただ「コードを見せる額縁」くらいだけ考えた。 しかし、実務でアニメーションがガラガラしたり、スクロールを下したときに画面が突き破られる現象(Jank)を経験しながら、私の考えは変わった。 「なぜ同じコードを編んでいるのにクロムでは柔らかく、Internet Explorer(IE)では途切れるのか?」 「なぜJavaScriptでスタイルを少し変えたのにCPUが上がるのか?」 わかると、ブラウザは単なる額縁ではありませんでした。ブラウザは、私たちが送ったテキスト(HTML / CSS)を解釈し、ピクセル一つ一つを数学的に計算して撮る巨大な「画家(Painter)」であり「建築家」だった。 過去の時間、私たちは大まかなネットワーク道路を通ってデータを無事に出荷しました。今回は到着したデータボックス(パケット)を開けて、ブラウザがどのように画面という絵を描くのか調べてみよう。これがRe:Booting CS基礎シリーズの最後の話です。 私たちの「デジタル物流センター」の世界観で、物事(HTMLファイル)が顧客の家(ブラウザ)に到着しました。しかし到着したのは完成品ではなく「組立説明書」だ。ブラウザエンジン(レンダリングエンジン)という作業チームはこのマニュアルを見てすぐに組み立てに入る。このプロセスをレンダリングパイプラインと呼びます。 最初に到着したHTMLテキストを読み、「スケルトン」を作成します。 次にCSSファイルを読んで「スタイルルール」を作成します。 今、スケルトン(DOM)とデザイン(CSSOM)を組み合わせます。ここで重要なのは、「実際に画面に見えるもの」だけを選び出すということです。 これは本当に重要なステップです。性能最適化の核心がここにある。レンダーツリーが作成されると、ブラウザは2つの重い作業を行います。 コードでこのコストの違いを感じましょう。 分析: 実務では、「アニメーションがうるさい」は、ほとんどの場合、 学部の時はこんなことを知らなかったので、JavaScriptでDOMを雑誌で操作した。 パフォーマンスを守るためのヒント: この記事の最後に、 [Re: Booting] CS基礎シリーズが停止しました。 私たちは長い旅をしました。 最初はただ就職のために月々覚えた知識だった。しかし、実務のエラーとぶつかり、再び覗いたCS(コンピュータ工学)は、死んでいる文字ではなく、私のコードを支える硬い地盤だった。 これで基礎工事は終わった。硬くなった地盤の上に本格的に自分だけの城を築く時間だ。次のシリーズ[Monolith Builder]では、私が実務で経験したSpring BootとVue.jsを活用したWebアプリケーションビルダーを扱う予定だ。 「理論」が「実践」になるその過程を期待してほしい。color: redを書くと赤になるのが当然だった。

到着した貨物、組み立てを開始する
ステップ1: 設計図の分析 (Parsing & DOM Tree)
<html>は根(Root)、<body>は幹、<div>は枝…ステップ2:インテリアデザイン(CSSOM Tree)
divは赤」「クラスがboxのやつはサイズ100px」ステップ3: 作業指示書の作成 (Render Tree)
display: none属性を持つ要素は?画面に表示されないものなので、レンダーツリーから除外される。(スペースも占有しない)visibility: hiddenは?見えないがスペースは占有するので、レンダーツリーに含まれる。
[Code Verification]リフロー(Reflow)とリペイント(Repaint)
const box = document.getElementById('box');
// Case 1: レイアウト(Reflow)を引き起こすコード(高コスト!)
// サイズや位置を変えると、周囲の要素の位置まで全部再計算される。
box.style.width = '200px';
box.style.height = '200px';
box.style.margin = '20px';
// Case 2: ペイント(Repaint)だけを引き起こすコード(比較的安い)
// 位置はそのままで、色だけ変える。計算なしで塗り直しだけで済む。
box.style.backgroundColor = 'blue';
box.style.color = 'white';
box.style.visibility = 'hidden';
widthの変更:建物のサイズを変える工事だ。隣の建物も押し出され、さらにその隣の建物も押し出される。ブラウザは全体の計算をもう一度やり直さなければならない。(Reflowが発生 -> パフォーマンス低下の主犯)colorの変更:建物のサイズはそのままで、ペンキを塗り直すだけだ。計算し直す必要はない。(Repaintが発生 -> 速い)width、left、topなどのレイアウト属性にリアルタイムで触れたために発生します。このような場合は、transformのような属性を使ってレイアウト計算をスキップするテクニックが必要です。実践的なアドバイス:ブラウザを悩ませないでください
for ドアを回しながら要素一つ一つの大きさを変え、スタイルを塗った。ブラウザの立場では、1秒に数十回ずつ建物を壊して再建する拷問に遭ったわけだ。
classをあらかじめ用意しておき、classNameだけを一度で切り替えよう。left、topの代わりにtransform: translate()を使えば、レイアウトの段階をスキップしてGPUが処理してくれる。display: none(レンダーツリーから除外)、場所だけ空けておくならvisibility: hidden(レンダーツリーに含まれる)と使い分けよう。
シリーズ1の終了:再起動した私のCS


