PageSpeedInsights APIとChrome機能を組み合わせて使ってみる

## はじめに

- 以前、[こちらの記事](https://qiita.com/enuswi/items/7889aa931606cb387dc3)で、PageSpeedInsights APIを用いる方法について書いてみたのですが、いざ実際にこのAPIを用いたパフォーマンス測定を開発サイクルに組み込むこもうと考えた時にあまりはまらなさそうだなと感じました。
- 他に何かないかなと思ったときに、何やらChromeのバージョン90から開発者ツールでCore Web Vitalsの計測ができるようになったとのことだったので試してみました。

## Core Web Vitalsって？

- 2020年5月にGoogleの検索ランキングに用いることが伝えられた指標です。

### LCP（= Largest Contentful Paint）

- 最大視覚コンテンツの表示時間

> 読み込みのパフォーマンスを測定するための指標です。優れたユーザー エクスペリエンスを提供するためには、ページの読み込みが開始されてからの LCP を 2.5 秒以内にする必要があります。


### FID（= First Input Delay）

- 初回入力までの遅延時間

> インタラクティブ性を測定するための指標です。優れたユーザー エクスペリエンスを提供するためには、ページの FID を 100 ミリ秒以下にする必要があります。

### CLS（= Cumulative Layout Shift）

- 累積レイアウト シフト数

> 視覚的な安定性を測定するための指標です。
優れたユーザー エクスペリエンスを提供するためには、ページの CLS を 0.1 以下に維持する必要があります。

- 出典： https://web.dev/i18n/ja/vitals/

## Chromeでの表示の仕方

![スクリーンショット 2021-11-21 18.34.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46053/267ed7fc-5376-8329-918c-0c6d44137aa2.png)

- ※ 上の画像だとFirst Input Delayの値が入ってませんが、クリック等の入力イベントに反応し計測されます。

## どう向上していくか（状況把握）

- 扱うサイトによってとくに重視すべき指標が変わってくるかと思いますが検索ランキングに関わってくるということであれば低いままにしておくわけにはいかないですね。
- 一旦、状況把握というところでいくと、前回使ったPageSpeedInsights API使えそうです。
    - 最大視覚コンテンツは `lighthouseResult.audits.largest-contentful-paint-element`
    - ズレたレイアウトについては `lighthouseResult.audits.layout-shift-elements`

#### 最大視覚コンテンツ

```json
"largest-contentful-paint-element": {
  "id": "largest-contentful-paint-element",
  "title": "Largest Contentful Paint element",
  "description": "This is the largest contentful element painted within the viewport. [Learn More](https://web.dev/lighthouse-largest-contentful-paint/)",
  "score": null,
  "scoreDisplayMode": "informative",
  "displayValue": "1 element found",
  "details": {
    "items": [
      {
        "node": {
          "boundingRect": {
            "left": 165,
            "top": 426,
            "right": 477,
            "bottom": 474,
            "height": 48,
            "width": 312
          },
          "type": "node",
          "path": "1,HTML,1,BODY,0,DIV,3,DIV,0,DIV,0,DIV,0,DIV,0,DIV,3,DIV",
          "lhId": "page-14-DIV",
          "nodeLabel": "PHPをメインにバックエンドエンジニアをやっています。フロントも時々やります！",
          "snippet": "\u003cdiv class=\"css-4znuir\"\u003e",
          "selector": "div.css-1j4z0qo \u003e div.css-1iymp9t \u003e div.css-1cw2pgk \u003e div.css-4znuir"
        }
      }
    ],
    "type": "table",
    "headings": [
      {
        "text": "Element",
        "key": "node",
        "itemType": "node"
      }
    ]
  }
}
```

![スクリーンショット 2021-11-21 20.40.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46053/6426cefe-4363-2be0-9b7a-8ceeb8ec9982.png)


#### ズレたレイアウト

```json
"layout-shift-elements": {
  "id": "layout-shift-elements",
  "title": "Avoid large layout shifts",
  "description": "These DOM elements contribute most to the CLS of the page.",
  "score": null,
  "scoreDisplayMode": "informative",
  "displayValue": "2 elements found",
  "details": {
    "headings": [
      {
        "text": "Element",
        "key": "node",
        "itemType": "node"
      },
      {
        "granularity": 0.001,
        "key": "score",
        "text": "CLS Contribution",
        "itemType": "numeric"
      }
    ],
    "items": [
      {
        "score": 0.0095744680851063829,
        "node": {
          "lhId": "page-15-FOOTER",
          "nodeLabel": "How developers code is here.\n© 2011-2021Increments Inc.\nGuide & Help\nAbout\nTerm…",
          "selector": "body \u003e div.allWrapper \u003e footer#globalfooter",
          "path": "1,HTML,1,BODY,0,DIV,5,FOOTER",
          "type": "node",
          "snippet": "\u003cfooter id=\"globalfooter\" class=\"st-footer\"\u003e",
          "boundingRect": {
            "bottom": 2481,
            "top": 2089,
            "width": 1350,
            "right": 1350,
            "left": 0,
            "height": 392
          }
        }
      },
      {
        "score": 2.0630417651694249e-05,
        "node": {
          "lhId": "page-16-A",
          "selector": "div.css-1iymp9t \u003e div.css-19kzrtu \u003e h2.css-hpde30 \u003e a.css-lrv4n2",
          "type": "node",
          "path": "1,HTML,1,BODY,0,DIV,3,DIV,0,DIV,0,DIV,1,DIV,0,DIV,0,H2,1,A",
          "boundingRect": {
            "left": 190,
            "top": 648,
            "width": 82,
            "right": 272,
            "height": 21,
            "bottom": 669
          },
          "snippet": "\u003ca href=\"/enuswi/following_tags\" class=\"css-lrv4n2\"\u003e",
          "nodeLabel": "Following tags"
        }
      }
    ],
    "type": "table"
  }
}
```

![スクリーンショット 2021-11-21 20.42.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46053/53c11091-c277-855b-85e0-16e2a407ea5a.png)

![スクリーンショット 2021-11-21 20.44.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46053/934e6c05-337c-6777-3ed5-e3886a193c54.png)

## 最後に

- LighthouseやPageSpeedInsightsは計測までに時間がかかることもあり、ちょっと面倒だなと思うのですが、今回のChrome機能を使えば簡単に指標の確認ができるので重宝しそうです。
- 「評価の低いページを見つける→PageSpeedInsights APIで状況確認→改善」というサイクルを一度、回してみようと思います！
- また[こちらのライブラリ](https://www.npmjs.com/package/web-vitals)を使うとGAに結果を送信することもできるとのことなので、次はそちらも試してみたいと思います。