lighthouseのスコアリング詳細


## 概要
lighthouseのperformace項目の評価指標とどのようにスコアを算出しているかについてのまとめです。

## 評価指標
![47a13957-272d-415c-9364-93b5ffad7365-1920x502r.png](https://qiita-image-store.s3.amazonaws.com/0/120529/af8516e2-84cb-33dd-f376-7fd2c54cb384.png)


lighthouseのperformanceでは上記6つの指標が利用されています。
最終スコアに影響するのは、Estimated Input Latencyを抜いた5つです。
以下、それぞれの指標について解説していきます。

### First Contentful Paint (コンテンツの初回ペイント)
![fe2e044d-98d0-4ee3-97a2-a8c520198443-1920x684r.png](https://qiita-image-store.s3.amazonaws.com/0/120529/c2d36289-21f9-b876-5bf7-3cfecdde8bd1.png)


First Contentful Paint (FCP) はブラウザがテキストや画像など何かしらのコンテンツをレンダリングし始めた時間です。
FCPのタイミングが遅い場合、

- サーバーのレスポンスが遅い 
- クリティカルレンダリングパスが最適化されていない 

などの原因が考えられます。

### First Meaningful Paint (意味のあるコンテンツの初回ペイント)
First Meaningful Paintはユーザーにとって何かしら意味のある (役に立つ) コンテンツが描画された時間を示します。
何を持って「意味のある」とみなすかは、Webページのコンテンツや性質によって異なるため標準化が難しく明確な仕様は策定されていません。
一般的にはそのWebページ内の最も重要なコンテンツが描画された時間に当たります。
![346f5a14-480b-4433-a320-a346e85c9796-1920x839r.png](https://qiita-image-store.s3.amazonaws.com/0/120529/9a330b5c-556b-c676-76ed-5cf6a5b10269.png)

レイアウトの変更を元にFMPの近似値を算出する評価アプローチについては、以下にまとめられてます。

- [Time to First Meaningful Paint: a layout-based approach](https://docs.google.com/document/d/1BR94tJdZLsin5poeet0XoTW60M0SjvOJQttKT-JK8HI/view?hl=ja)

### Speed Index (速度インデックス)
Speed Indexは他の指標とは少し変わった指標になります。
他の指標は基本的にあるタイミング(マイルストーン)に到達するまでの時間を評価するのに対して、Speed Indexはページロードが完了するまでのプロセスを評価するための指標です。
![1d575c18-c410-4057-a15b-42ec5d42f810-1920x506r.png](https://qiita-image-store.s3.amazonaws.com/0/120529/284dcfe6-2cfc-0d7d-51a6-7cb6d4557125.png)

この画像は2つのページ(上がA、下がB)のロードが完了するまでのキャプチャですが、AとBはロード完了までの時間は同じですが、Aは早い段階 (1.0s) でFirstViewの大半が描画されているのに対して、Bは後半 (11.0s) に描画されています。
この場合、AとBを比較するとAの方がパフォーマンスが優れている(Speed Indexは低い)ということになります。

このページロードの進捗をX軸を経過時間、Y軸を描画割合としてグラフで表すと、以下のようになります。
![91de57c1-9b6c-4634-b1d7-81c105511fcb-1920x1408r.png](https://qiita-image-store.s3.amazonaws.com/0/120529/3d8c9592-aaf3-e020-e8ad-1b1428856594.png)


また、AとBの未表示領域を比較すると以下のようになります。
![cbc3b080-9b1a-439e-b7c0-776795f54fa2-1920x725r.png](https://qiita-image-store.s3.amazonaws.com/0/120529/db60a2af-171d-1d39-e538-98215bba02e4.png)

図を見ても分かる通り、SpeedIndexは (単位時間×未描画領域割合) の総和になります。
そのため、SpeedIndexの値が低いほど優れているということになります。
注意点としてはSpeedIndexはページ全体の描画量ではなく、Viewport内の範囲(FirstView)の表示割合をみています。

このときどうやって、「描画されている割合」を算出するかについてですが、主に以下の2つの方法があります。

 1.  単位時間ごとにキャプチャを残しておき、最終的に表示された画面と経過時間時点での画面との差分からどのくらいの割合が描画されているかを判定
 2.   ブラウザのLayoutイベント等から判定

パフォーマンス測定サービスの[webpagetest](https://www.webpagetest.org/)では1、lighthouseでは[speedline](https://github.com/paulirish/speedline)というツールを使って2の方法で計測しています。

最終画面との比較によっての算出になるため、FirstView内でサイズの大きい画像を読み込んだり、カルーセルなど後からjavascriptを用いて動的にコンテンツを表示したりすることは、SpeedIndexにおいては不利に働きやすいと言われています。

### First CPU Idle (CPU の初回アイドル)
First CPU Idle (FCI) は、ブラウザのメインスレッドがアイドル状態 (待ち状態) になり、ユーザーの入力を受け付けられると想定されるタイミングを示します。

算出のアプローチについては、First Meaningful Paint以降、最初にブラウザのメインスレッドでLong Task(50ms以上のタスク)が5秒間発生していないタイミングを求めるといった方法がありますが、First Meaningful Paint自体が標準化されていない指標のため、FCIもまた標準化されているわけではありません。

### Time to Interactive (インタラクティブになるまでの時間)
Time to Interactive (TTI) は、FCIと似てますが、Web ページのロードが終わりユーザーの入力に対してすばやく応答できると予想されるタイミングを指します。

算出は、First Meaningful Paint以降、最初にネットワークリクエストが2回以内に収まり、ブラウザのメインスレッドでLong Task(50ms以上のタスク)が5秒間発生していないタイミングを求めるといった方法がありますが、FCIと同じく標準化されているわけではありません。
![30b1c485-377e-40cf-82db-4ac579720841-1920x1124r.png](https://qiita-image-store.s3.amazonaws.com/0/120529/20590b41-8c89-3ac7-dc20-d5ebb1091772.png)


算出アプローチの詳細については以下にまとめられています。

- [First Interactive and First Consistently Interactive](https://docs.google.com/document/d/1GGiI9-7KeY3TPqS3YT271upUVimo-XiL5mwWorDUD4c/edit#)

分析や広告タグを読み込むとなぜパフォーマンスが悪くなるのかという疑問が上がることがありますが、一般的にはそういったサードパーティーのスクリプトは、1つ読み込むだけでもその先でリダイレクトし複数のリクエストを発生させ、ブラウザのメインスレッド内でスクリプトの解析や処理を行うため、上記のFCIやTTIのタイミングを遅らせます。(同期的に読み込むスクリプトは、コンテンツの表示自体も遅らせるので更に影響ありますが、、)

同様に、Twitter, Facebook, YoutubeなどのSocial Widgetなどもperformanceを劣化させる要因になり得るので導入の際には注意が必要です。AMPでスクリプトを制限しているのもこういった理由からです。

もちろんそういったタグを全く読み込まないということは厳しいので、極力無駄なタグは読み込まない努力が必要です。

### Estimated Input Latency (入力の推定待ち時間)
Estimated Input Latencyは、ユーザーの入力(操作)に応答するまでの推定時間です。
この指標は直接最終スコアには影響しませんが、ユーザーに快適な操作を提供するために必要な指標です。

この指標の元となる思想には、[RAIL パフォーマンスモデル](https://developers.google.com/web/fundamentals/performance/rail?hl=ja) というものがあり、それによるとユーザーの入力に対して100ms以内に応答することが理想とされています。

## 評価指標の重み付け

lighthouseは上記の指標すべてを均等にトータルスコアに反映しているわけではなくそれぞれの指標に重みを付けてスコアを計算しています。
それぞれの指標の重みに関しては以下の通りです。

- First Contentful Paint => 3
- First Meaningful Paint  => 1
- Speed Index => 4
- First CPU Idle => 2
- Time to Interactive => 5
- Estimated Input Latency => 0

この指標の重み付けについてはGoogleが資料を公開しています。

- [Lighthouse v3 Score Weighting](https://docs.google.com/spreadsheets/d/1Cxzhy5ecqJCucdf1M0iOzM8mIxNc7mmx107o5nj38Eo/edit?hl=ja#gid=0)

同じシート内に [ScoringCalculator](https://docs.google.com/spreadsheets/d/1Cxzhy5ecqJCucdf1M0iOzM8mIxNc7mmx107o5nj38Eo/edit?hl=ja#gid=283330180) を用意してくれており、これによってどの指標がどの程度短縮されたらどのくらいのスコアになるかの試算や、スコア90になるためにはどの指標をどの程度縮める必要があるかの逆算などが行えます。

[補足] 上記はlighthouse v3の重み付けですが軽く試してみたところv4でも重み付け自体は変わっていなそうでした。


--- 
### 参考
- [ユーザー中心のパフォーマンス指標](https://developers.google.com/web/fundamentals/performance/user-centric-performance-metrics)
- [Speed Index - WebPagetest Documentation](https://sites.google.com/a/webpagetest.org/docs/using-webpagetest/metrics/speed-index)