Lighthouse のパフォーマンス計測時はスロットリングを活用しよう

## これは

  

Webページのパフォーマンスを計測する際には、Lighthouseがよく利用されますが、同じWebページでも以下の要因によってパフォーマンススコアは変動するため、注意が必要です。

- 利用しているデバイスのスペック（CPU）
- ネットワークの通信速度

そこで、本記事ではこれらの要因を調整するためのLighthouseのスロットリング機能について簡単に解説します。
  

## 背景

  

筆者がサイトのパフォーマンス計測を実施した際、以下の2つの方法で計測したスコアに乖離があることに気づきました。

- 手元のマシン（Mac）でブラウザのDevToolsから実行したスコア
- CI（GitHub Actions）上でCLIから実行したスコア

前者は平均で95点前後であるのに対し、後者は平均で70点前後と大きな違いがありました。実行環境のスペック差異が原因であることが分かり、これを受けてスロットリングについて調査することにしました。

## スロットリングについて

スロットリングの意味は以下の通りです。

>**スロットリング**とは、システムの過負荷や特定利用者による資源の独占を回避するため、一定の制限値を超えた場合に意図的に性能を低下させたり、要求を一時的に拒否したりする制御のこと。

https://e-words.jp/w/%E3%82%B9%E3%83%AD%E3%83%83%E3%83%88%E3%83%AA%E3%83%B3%E3%82%B0.html

特に開発者は実際のユーザーの環境（デバイス、ネットワーク等）よりも優れている環境で作業する場合が多いため、スロットリングによってより実態に即した形で検証が可能になります。

特にLighthouseには「ネットワークスロットリング」と「CPUスロットリング」の2種類が存在します。



### ネットワークスロットリング

ネットワークスロットリングは、ネットワークの通信速度を意図的に低下させることで、実際のユーザー環境に近い状況で計測できる仕組みです。
執筆時点ではモバイル向けのネットワークスロットリングのデフォルト設定は以下の通りです。

-   レイテンシ：150ms
-   スループット：1.6Mbps（ダウンロード）／750 Kbps（アップロード）

Devtools、CLIのどちらにおいても、モバイル環境で実行した場合、デフォルトでは以下のように「Slow 4G」が適用されます。

![Screen Shot 2023-12-01 at 15.10.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/451272/d5d29243-a74f-7828-6eb7-d1a26603e39a.png)


また上記の設定は[Lighthouseのrepositoryの定数](https://github.com/GoogleChrome/lighthouse/blob/main/core/config/constants.js#L21C9-L21C9)で定義されています。

#### ネットワークスロットリングの種類

以下の4種類があります。

- Simulated throttling（シミュレートされたスロットリング）
    - デフォルトで適用される。スロットリング無しで実行した結果を基にシミュレーション（推定）を行う
- Request-level throttling（リクエストレベルのスロットリング）
    - DevToolsスロットリングとも呼ばれ、その名の通りリクエストレベルでスロットリングを行う
- Proxy-level throttling（プロキシレベルのスロットリング）
- Packet-level throttling（パケットレベルのスロットリング）


※プロキシレベル、パケットレベルのスロットリングについては本記事では割愛


パケットレベルのスロットリングについては以下の記事で詳しく説明されています。

[Full Throttle: Comparing packet-level and DevTools throttling](https://blog.webpagetest.org/posts/full-throttle-comparing-packet-level-and-dev-tools-throttling/)


### CPUスロットリングについて

デバイスのスペック（CPU）を意図的に下げることで、ユーザーの環境により近い形で計測を行う仕組みです。

Lighthouseでは各レポートごとに、ホストデバイスのCPUパフォーマンスの近似値として`benchmarkIndex`という値を算出し、スロットリングの指標に用いています。

以下は各デバイスクラスの比較表です（参考：[Network Throttling](https://github.com/GoogleChrome/lighthouse/blob/main/docs/throttling.md)）

| -                                   | High-End Desktop | Low-End Desktop | High-End Mobile | Mid-Tier Mobile | Low-End Mobile    |
| ----------------------------------- | ---------------- | --------------- | --------------- | --------------- | ----------------- |
| Example Device                      | 16" Macbook Pro  | Intel NUC i3    | Samsung S10     | Moto G4         | Samsung Galaxy J2 |
| **Lighthouse BenchmarkIndex**           | 1500-2000        | 1000-1500       | 800-1200        | 125-800         | <125              |
| Octane 2.0                          | 30000-45000      | 20000-35000     | 15000-25000     | 2000-20000      | <2000             |
| Speedometer 2.0                     | 90-200           | 50-90           | 20-50           | 10-20           | <10               |
| JavaScript Execution of a News Site | 2-4s             | 4-8s            | 4-8s            | 8-20s           | 20-40s            |


ちなみに手元のM2 Macbookの`benchmarkIndex` は `2800`程度であり、表の High-End Desktop よりもかなり高い数値になっているようです。

また各デバイスクラスでどの程度のスロットリングが必要かは下記表の通りです。

| -                | High-End Desktop | Low-End Desktop | High-End Mobile | Mid-Tier Mobile | Low-End Mobile |
| ---------------- | ---------------- | --------------- | --------------- | --------------- | -------------- |
| High-End Desktop | 1x               | 2x (1-4)        | 2x (1-4)        | 4x (2-10)       | 10x (5-20)     |
| Low-End Desktop  | -                | 1x              | 1x              | 2x (1-5)        | 5x (3-10)      |
| High-End Mobile  | -                | -               | 1x              | 2x (1-5)        | 5x (3-10)      |
| Mid-Tier Mobile  | -                | -               | -               | 1x              | 2x (1-5)       |
| Low-End Mobile   | -                | -               | -               | -               | 1x             |

表によると、

- High-End Desktop で High-End Mobile の速度にするなら2倍遅く
- Low-End Desktop で Low-End Mobile の速度にするなら5倍遅く

する必要があります。



## Lighthouseでのスロットリングの設定


### DevToolsでの設定方法

Performanceタブから設定します。
（[公式ガイド](https://developer.chrome.com/docs/devtools/performance?hl=ja#simulate_a_mobile_cpu)）

![Screen Shot 2023-12-01 at 13.24.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/451272/641d6ad1-1b33-ea31-742b-88e9f511e359.png)

- CPU: `4x`、`6x`
- Network: `Fast 3G`, `Slow 3G`、`Offline`、`Custom`

から選択できます。


ネットワークスロットリングはNetworkタブからも設定ができます。
（[公式ガイド](https://developer.chrome.com/docs/devtools/network?hl=ja#throttle)）

![Screen Shot 2023-12-01 at 13.27.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/451272/c4504914-f23c-4048-ba85-a75339c7c258.png)

 また`Custom`から独自のスロットリングを追加できます。

![Screen Shot 2023-12-01 at 13.32.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/451272/bcff60d0-4071-596a-970c-5319c62f15aa.png)

- Download/Upload速度（Kbps）
- Latency（ミリ秒）

で指定ができます。

（[公式ガイド](https://developer.chrome.com/docs/devtools/settings/throttling?hl=ja)）
 

 ### CLIでの設定方法

（参考：[CLI Options](https://github.com/GoogleChrome/lighthouse/tree/main#cli-options)）

スロットリング関連のオプションは以下があります。

```
  --throttling-method                  スロットリング方法。 "devtools", "provided", "simulate"から選択
  --throttling.rttMs                   ネットワークRTT（TCP層）
  --throttling.throughputKbps          シミュレートしたダウンロード速度
  --throttling.requestLatencyMs        ネットワークRTT（HTTP層）
  --throttling.downloadThroughputKbps  エミュレートしたダウンロード速度
  --throttling.uploadThroughputKbps    エミュレートしたアップロード速度
  --throttling.cpuSlowdownMultiplier   CPUスロットリングの値。数値をかけた分だけ遅くなる
```

`throttling-method`については以下の３つから指定できます。

- `devtools`: DevToolsのスロットリング設定を元にエミュレーションする
- `provided`: Lighthouseの設定ファイルを元にエミュレーション
- `simulate`: エミュレーションは行わず、内部でシミュレーション（推定）する

※上記について詳細な情報を見つけることが出来ず、詳しい方いらっしゃれば教えていただけると幸いです

スロットリングのシミュレーションの仕組みについては下記の記事で詳しく説明されています。

[How does Lighthouse simulated throttling work?](https://calendar.perfplanet.com/2021/how-does-lighthouse-simulated-throttling-work/)


以上です。

## 参考記事

- https://github.com/GoogleChrome/lighthouse/blob/main/docs/throttling.md
- https://qiita.com/nightyknite/items/22d9f818dbab9bf171a3
- https://engineering.mercari.com/blog/entry/20220329-02e2d821b8/
- https://www.slideshare.net/tyamadajp/ss-238342843