Core Web Vitalsを改善するためにPerformanceタブで分析する

[Qiita株式会社のカレンダー](https://qiita.com/advent-calendar/2022/qiita-inc)の16日目は @kyntk が担当します。

---

Core Web Vitalsの改善をするために、ブラウザでの分析をすることがありました。
その際にPerformanceタブを使ったのですが、Performanceタブはとても機能が多くて情報が多い分、慣れないとその情報が何を示しているのか分かりづらいなと感じました。

そこで今回は、リクエストからLCPと、その後のMain threadの状態を分析するために、Performanceタブでどのあたりを見たのかを順にまとめていきます。

## 環境

- ブラウザ: Chrome バージョン108
- 対象のページ: [【Mermaidの紹介】Qiitaでダイアグラム・チャートが簡単に書けるようになりました！ - Qiita](https://qiita.com/Qiita/items/c07f3262d8f3b25f06c9)

## LCPまで

Chromeでパフォーマンスタブを開いて分析をしていきます。
今回はMobileで、CPU: `4x slowdown`, Network: `Fast 3G`にスペックを下げて分析していきます。(LighthouseのMobileでのデフォルトスペックです)

reloadボタンを押すと、以下のように結果が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143317/fb357315-d637-d2db-5759-787a94c2d478.png)

はじめに、LCPまでに何が起きているのかを見ていきます。

timingにLCPが表示されているので、このあたりまでを見ていきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143317/37c9dfb2-0d5d-8f72-ddad-dc2c7e3d54ef.png)

LCPまでに起きることはアプリケーションによって異なるので注意ください。
詳しくはこちらの記事にまとめてあります。

https://qiita.com/kyntk/items/1f69a80476294713082b

青いバーはHTMLのダウンロードを示しています。
このバーのうち、左側の線はリクエスト送信前のコネクション開始を示し、薄い青のバーはリクエストしてからTTFBまで、濃い青のバーはContent Download、そして右側の線はメインスレッドの空きを待っている時間を示しています。[^1]

[^1]: [Performance features reference - Chrome Developers](https://developer.chrome.com/docs/devtools/evaluate-performance/reference/#network)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143317/6396d0b5-3cb8-8249-f4f3-c2062cf8b9a5.png)

HTMLのダウンロードが始まると、pagehideが行われています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143317/22c57bfa-f19d-4492-039e-6fc68b4a5fc9.png)

その後、CSS(紫)とJS(黄色)のリクエストを開始します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143317/3755522a-fc58-77c9-0f9c-9249c668528b.png)

最初に現れる Parse HTMLを見てみると、Rangeが`[0...13]`となっています。
この行にある処理でHTMLのParseがブロックされているようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143317/21a452f4-c5b5-e50f-08b6-f5a074628ccf.png)

先程ダウンロードしたCSSのParseをしています。
Summaryを見ると、どのファイルが対象かも確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143317/35a655ac-5e7e-6215-cbf1-9a592d37a681.png)

次にEvaluate Scriptが確認できます。
Summaryタブから対象を確認すると、head要素内にかかれているScriptのようです。
Evaluate ScriptではCompile ScriptとCompile Codeをしています。これはV8が実行時にJITコンパイルするためだと思われます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143317/0e4736d9-2d29-c8cb-0024-d7dd7af1c18d.png)

次のEvaluate Scriptはhead要素内でasyncで読み込んでいたScriptです。
asyncをつけると、ダウンロードが完了後にJavaScriptが実行されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143317/45dc2e49-23d6-6ecc-9d95-2f3c70e74ded.png)

ちなみにこのJavaScriptの情報については、Networkで対象のファイルをクリックすると、ファイルサイズやダウンロードにかかった時間などが確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143317/f2798d11-03ea-b7df-a530-24be612a5bfd.png)

それが終わると、HTMLのParseを再開します。今度は`[14...54]`が対象です。
Parse中にJavaScriptが含まれるので、Evaluate Scriptも行われています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143317/4a888c04-fa4c-5d58-24f9-dd406dd792d1.png)

Recalculate Styleで、レンダーツリーを構築するためのスタイルの計算をしています。[^2]
HTMLのパース結果とCSSのパース結果を使います。カスケードの計算もされます。

[^2]: [How browsers work](https://web.dev/howbrowserswork/#style-computation)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143317/056c707f-e766-2d9c-a2b6-aca41a361e8a.png)

続くLayoutでは位置やサイズの計算を行い、Pre-Paintでプロパティの計算をします。
そしてPaintで作成されたレンダーツリーが画面に描画されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143317/2aa9af0d-b503-8d6b-8473-1d8da636c6a4.png)

ここでFirst Paint、First Contentful Paintがやってきます。
その後Run Microtasks、一部のStylesheetのParseをしています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143317/3bc4c0e1-7145-bdec-d2b5-dcfcb20eec90.png)

LCPまでは、残りのHTMLのパースをしてJavaScriptを実行したり、XMLHttpRequestをしたり、Renderツリーの再計算をしたり、ScriptのEvaluateをしたりを繰り返していました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143317/444d57fb-2e7d-af87-7842-0a37e6f40293.png)

またLCPまでにCSS、JavaScript、FontがダウンロードされていることがNetworkで確認できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143317/04e80c5e-0dc3-aab4-18e0-a1202552eb65.png)

## LCP以降

LCP以降もJS、画像等のリクエストが発生しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143317/d9eed828-0521-61e4-d1ea-78a4e9b12da4.png)

また、hydrateやその他のJavaScriptの処理が行われています。
ただ、本番のJavaScriptはビルド時点で最適化をしてしまっており、Performanceタブだけを見ても実際のソースコードと紐付けが難しい状態です。
そのため、どこに時間がかかっているかを分析するのは開発環境のほうが確認しやすいです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143317/16771de8-0e0a-f27b-9f11-e0f05c5a3486.png)

その際に、Call TreeやBottom-Upタブを見ると、どの処理に時間がかかっているのかを確認することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143317/fad20821-b05a-a64e-aa33-a4c831c7bf01.png)

## まとめ

Performanceタブを見ていくと、どのタイミングで何のリクエストが走って、どこが処理されているかなどを分析することができます。
この後、どこに時間がかかっているのか、無駄な処理はないかなどを見ていきながら、課題を見つけていきます。

それぞれの要素が何を指しているのかが分からないときはリファレンスを見てみてください。

https://developer.chrome.com/docs/devtools/evaluate-performance/reference/

また、パフォーマンスアップ関連でその他にも記事を書いているので良ければ見てください

1. [【Core Web Vitals】Webパフォーマンスを改善するなら、まずは重要な指標について理解しよう](https://qiita.com/kyntk/items/7ae8763961b62111889e)
2. [Lighthouse CI + Datadogを使ってパフォーマンスを継続的に計測する](https://qiita.com/kyntk/items/2086ece17387dccea61c)
3. [開発者ツールのLighthouseを使いこなせてますか？](https://qiita.com/kyntk/items/80a88f0894657a815cf8)
4. [LCPの改善でLighthouseだけ見てない？効果的に改善していくためのステップ](https://qiita.com/kyntk/items/1f69a80476294713082b)
5. [新しいパフォーマンス指標のINPをChrome UXレポートで見れるように設定する](https://qiita.com/kyntk/items/71bd88f97cd751616681)

---

[Qiita株式会社のカレンダー](https://qiita.com/advent-calendar/2022/qiita-inc)17日目は @ohakutsu と@taka-k が担当します！

ぜひ、[Qiita株式会社のカレンダー](https://qiita.com/advent-calendar/2022/qiita-inc)を購読設定して、明日の記事もご覧いただけると嬉しいです。

## Ref

- [Analyze runtime performance - Chrome Developers](https://developer.chrome.com/docs/devtools/evaluate-performance/)
- [Performance features reference - Chrome Developers](https://developer.chrome.com/docs/devtools/evaluate-performance/reference/)
- [Timeline Event Reference - Chrome Developers](https://developer.chrome.com/docs/devtools/evaluate-performance/performance-reference/)
- [Performance insights: Get actionable insights on your website's performance - Chrome Developers](https://developer.chrome.com/docs/devtools/performance-insights/)
- [RenderingNG - Chrome Developers](https://developer.chrome.com/articles/renderingng/)
- [Overview of the RenderingNG architecture - Chrome Developers](https://developer.chrome.com/articles/renderingng-architecture/)