【INP理解】ブラウザアドレスバーURL入力からWebページ表示の全工程と調査
PageSpeed Insightsを使ったTBT(Total Blocking Time)やLCP(Largest Contentful Paint)の対策が進むと、速くなった分、ユーザーが早期に操作できるため、javascriptの遅いイベントハンドラや同期処理が露呈します。
今まで露出していなかった「ユーザー操作に対する見た目の反応が出るまでの総所要時間」として、INP(Interaction to Next Paint)の遅延が目立ち始めます。
INP、LCP、CLSなど、CoreWebVitalsを理解して対応するためには、ユーザーがブラウザからhttp(s)リクエストをWebサーバーに送り、ブラウザにレスポンスが返され、Webページがブラウザに表示されるまでの工程を把握し、どの工程でボトルネックが発生しているのか?理解する必要が有ります。
INPの悪化要因3分類
- メインスレッドを占有するjavascriptイベントの長いタスク
- 各種ブラウザ工程の長いタスク
- javascriptイベント⇔Rendering(ブラウザ)の繰り返し
1. メインスレッドを占有するjavascriptイベントへの対処
javascriptのイベント処理を細かく分割し、メインスレッドを占有しないように細かくイベントループへ主導権を返す
メインスレッド(実行する場所)
ブラウザのUI・JS・スタイル計算・レイアウト・ペイントを実行する一本のスレッド。基本的に同時に1つのタスクしか動かない。
イベントループ「何をいつ実行するか、回す仕組み」
現在のイベントループ内で即実行するキュー(マイクロタスク)と次のイベントループで実行するキュー(マクロタスク)を取り出し順に実行し、空いたら描画フェーズへ進める。
※キュー:queue = 待ち行列
【INP理解向け】ブラウザでWebページが表示されるまでの全工程
- ブラウザのアドレスバーにURLを入力
- DNSによる名前解決
- お名前ドットコムなどのICANN公認レジストラやリセラーで名前解決、リクエスト先(サーバ)のIPアドレスを確認
- TCP接続の確立(ブラウザとWebサーバの間)
- 確認したIPアドレスのサーバーとブラウザで 3 Way HandShake によるTCP接続を確立
- httpsなら、TLSハンドシェイクも行われ通信が暗号化される
- http(s)リクエスト送信(ブラウザ→Webサーバ)
- ここでやっとブラウザからWebサーバにhttp(s)リクエストが送信される
- リクエストヘッダーを含むGETリクエストなどのhttp(s)メソッドで。
- ここでやっとブラウザからWebサーバにhttp(s)リクエストが送信される
- http(s)レスポンス受信(Webサーバ→ブラウザ)
- ステータスライン、レスポンスヘッダ、レスポンスボディ(html、css、javascript、画像、フォント、json、動画、音声などのコンテンツを含む)
- Loading(ブラウザ)
- Download
- サーバからhtml,css,javascript,画像,...をダウンロード
- Parse(構文解析)
- 構文解析し、DOM(Document Object Model)ツリーやCSSOM(CSS Object Model)ツリーに変換
- Download
- Scripting(ブラウザ)
- Parse工程でDOMができているため、ここでJavascriptを実行
- Rendering(ブラウザ)
- CalculateStyle(スタイル計算)
- DOM要素に対しCSSプロパティの割当を計算し、CSSルールのCSSセレクタを総当りでマッチ試行。個々のDOM要素にどのようなCSSプロパティが適用されるか判断
- Layout(レイアウト)
- DOM要素に対するCSSプロパティ算出後に、DOMツリーの全ノードにレイアウト計算とレイアウトを行う。
- CalculateStyle(スタイル計算)
- Painting(ブラウザ)
- Paint(描画命令の作成)
- 2Dグラフィックエンジン向けの命令の列を生成。ブラウザ種類やバージョンでグラフィックエンジンが異なるため、ここで差が出てくる。
- Rasterize(描画命令からビットマップ化)
- 生成された命令の列をもとにピクセル(ビットマップ)へ、レイヤーごとに描画。レイヤーが生成されるのは要素に対してposition,transform,opcityなどのプロパティが適用されているとき。
- CompositeLayers(レイヤー合成)
- ラスタライズで出来たピクセルレイヤーを合成し、最終レンダリング結果を生成。レイヤーはCPUによる合成、GPU合成されるものも有り。
- Paint(描画命令の作成)
参照元
調査にはブラウザのシークレットウィンドウを使う
- javascriptのイベントのボトルネック
- ブラウザのスタイル計算、レイアウト、描画などのボトルネック
調査時には、ブラウザキャッシュの影響を避けて再現性を重視します。
シークレットウィンドウのChrome開発者ツールでモバイルエミュレータが開いた状態をつくり、PerformanceタブのRecordボタンを押す、この後、計測対象のURLをアドレスバーに入力、実際に想定されるユーザーのアクションを実施、という流れでPerformance計測を行うと再現性を幾分か高められます。
※「Record」ボタンの右隣に、「Record and reload」ボタンもあります。
1回計測するたびに、ブラウザ内のタブではなくシークレットウィンドウ丸ごと、新規に開く/新規で閉じるを繰り返すことでPerformance計測を行い、ブラウザキャッシュによる再現性の低下を防ぎます。
Chromeブラウザ開発者ツールのPerformanceタブで調査
「5. http(s)レスポンス受信(Webサーバ→ブラウザ)」以降についての調査方法です。
事象の再現性が完全ではないのでベストな調査方法とは言えないですが、すぐ手軽にできる調査方法です。
- Chromeブラウザ開発者ツールを開き、Performanceタブをクリック
- Recordボタンをクリック
- 調査対象のWebページを開きスクロールやクリック(タップ)などのアクションを行う
- stopボタンをクリック
- タイムラインのMainスレッドで▶マークを▼に展開
- タイムラインをマウススクロールで最大までズームする。
- 1つのTaskの中で行われているEvent:scroll(Scripting)、Pre-paint(Rendering)、Paint(Painting)などを確認。
50msを超えるTaskは、タイムライン上のTaskの帯に赤い斜線が入り、LongTaskと表示されるようになっているため、赤い斜線を探し、前後関係や全体の流れの中で何をしているのか特定していきます。
javascriptのイベントとブラウザ工程の違い
- javascriptのイベント
- 「Event:」が先頭に付いている。
- 「8. Rendering(ブラウザ)」の「スタイル計算」や「レイアウト」、「9. Painting(ブラウザ)」の「Paint(描画)」工程など
- 「Event:」が先頭についていない。
調査対象のイベントやブラウザ工程がソースコード内のどこに該当しているか
PerformanceタブでTask、Event、ブラウザ工程などをそれそれクリックし、下部の「Bottom-up」や「Call tree」で「Activity」に記載されたパスや行数で確認できます。
▼を展開しても該当するjavascriptファイルパスや行数が存在しない場合
ブラウザの工程名であるため、▼を展開しても該当するjavascriptファイルパスや行数が存在しない場合、前後のjavascriptイベントを探し、そのjavascriptの前後をメインドキュメントhtmlで特定し、ブラウザ工程を模索します。
ホバーとスクロールのINP
INPにはホバーやスクロールのイベントが入ってないです。
INPが認識するユーザーインタラクションには、クリック、タップ、キーボード入力などがあります。ホバーやスクロールは INP では考慮されませんが、キーによるスクロールは他のイベントをトリガーする可能性があり、これらは INP が計測します。インタラクションは、JavaScript、CSS、ブラウザの組み込みコントロール、またはこれらの組み合わせによって駆動されます。
