Lighthouse CI Actionでwebページ表示速度を定期収集する

## はじめに
この記事はトラストバンク[Advent Calender 2022](https://qiita.com/advent-calendar/2022/trustbank)の記事です。

パブリテック事業部の大場です。
SREとして、「Logoフォーム」の保守運用やインフラ関連の業務を主に担当しています。
「LoGoフォーム」はブラウザでご利用頂くサービスですので、Webページの表示速度をモニタリングをしているのですが、以前、使用しているツールが不調で正確に取得できていないということがありました。

別の方法でも取得したいと考えていたところ、ちょうどGitLabからGitHubに移行することが決まり、GitHub の勉強も兼ねてGitHub ActionsでWebページの表示速度を収集する環境をつくってみました。

やったことはシンプルに、
**・定期的にLoGoフォームの画面表示にかかる時間を計測
・計測した時間をスプレッドシートに記録**
です。

## Lighthouseを使って計測

https://github.com/marketplace/actions/lighthouse-ci-action

LighthouseはWebサイトのパフォーマンス測定やアクセシビリティ、SEOなどを評価してくれる便利なツールです。Lighthouse CI Actionを利用すると、同じ測定をGitHub Actionで実行できます。

workflowのymlは以下のように設定しました。
```lighthouse_test.yml
name: Lighthouse CI
on:
  schedule:
  - cron: '0 * * * *'
jobs:
  lighthouse:
    runs-on: ubuntu-latest
    timeout-minutes: 180
    steps:
      - uses: actions/checkout@v3
      - name: Audit URLs using Lighthouse
        uses: treosh/lighthouse-ci-action@v9
        with:
          urls: |
            https://<logoformのtopページのURL>
          configPath: "./lighthouserc.json"
          temporaryPublicStorage: true
          uploadArtifacts: true
```

```lighthouserc.json
{
  "ci": {
    "collect": {
      "settings": {
        "preset": "desktop",
        "numberOfRuns": 3,
        "maxWaitForLoad": 90000
      }
    }
  }
}
```
* 実行タイミングを`毎時0分`
* タイムアウトを`180秒`
（1度、処理が終わらず長時間実行していたことがあったので設定しておいた方がよさそうです）
* 計測するページはLoGoフォームのTOPページ
* lighthousの細かい設定は、リポジトリの直下に`lighthouserc.json`を作成し、それを読み込んでいます
    * 主にPCでの利用を想定しているため、`desktop`を指定
    * 1度に計測する回数は`3`回
    * ロード時間上限は90秒（`90000`ミリ秒）
* 計測した結果を後で利用するため、`temporaryPublicStorage`を`true`に設定
trueにすると、一時領域（.lighthouseci/）にjsonの計測結果が出力されます
* `uploadArtifacts`は今回必須な設定ではありませんが、計測結果のファイルを目視で確認したい場合は必要になります

これで、毎時0分にワークフローが実行されArtifactsにjsonとhtmlが出力されますので、以下のように計測結果を確認することができます。
* json
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958831/aaf87bc8-1c7b-a8b7-b443-9f9949f84bc0.png)
* html
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958831/93dc99fe-10be-50b6-e089-b5717a5a82c4.png)


## 計測結果をスプレッドシートに記録
計測結果として一時領域（.lighthouseci/）に出力されたjsonから、実行日時とページ表示時間をスプレッドシートに記録するコードを用意します。
スプレッドシートへの記録は以下を参考にしました。
[PythonでGoogle Sheetsを編集する方法](https://www.twilio.com/blog/an-easy-way-to-read-and-write-to-a-google-spreadsheet-in-python-jp)
```sample.py
import os
import glob
import json
import gspread
from oauth2client.service_account import ServiceAccountCredentials

# 計測結果をjsonから実行日時とページ表示時間を取得
FILENAME = '.lighthouseci/lhr-*.json'
l_files = glob.glob(FILENAME)

f = open(l_files[0], 'r')
d_json = json.load(f)

s_date = d_json['fetchTime']
s_spdtime = d_json['audits']['speed-index']['numericValue']

# スプレッドシートをオープン
scope =['https://spreadsheets.google.com/feeds', 'https://www.googleapis.com/auth/drive']
creds = ServiceAccountCredentials.from_json_keyfile_name('client_secret.json', scope)
client = gspread.authorize(creds)
sheet = client.open("lighthouse_data").sheet1

# 最終行の下に記録
row = [s_date, s_spdtime]
l_col = list(filter(None, sheet.col_values(1)))
i_index = len(l_col)+1
sheet.insert_row(row, i_index)
```
これを先ほどのワークフローに組み込みます。
```lighthouse_test.yml
name: Lighthouse CI
on:
  schedule:
  - cron: '0 * * * *'
jobs:
  lighthouse:
    runs-on: ubuntu-latest
    timeout-minutes: 180
    steps:
      - uses: actions/checkout@v3
      - name: Audit URLs using Lighthouse
        uses: treosh/lighthouse-ci-action@v9
        with:
          urls: |
            https://<logoformのtopページのURL>
          configPath: "./lighthouserc.json"
          temporaryPublicStorage: true
          uploadArtifacts: true
      - name: Setup Python
        uses: actions/setup-python@v2
        with:
          python-version: '3.8'
          architecture: 'x64'
      - name: Get Python version
        run: python -V
      - name: Install dependencies
        run: pip install -r requirements.txt
      - name: Run Python
        run: python sample.py
```
lighthouse実行後にpythonの実行環境を準備し、作成したsample.pyを実行しています。
スプレッドシートにも記録されました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958831/3f5f566b-f76a-b899-c797-e0e37ff7eeed.png)
sheduleで設定した時刻から10~15分ほど時間差が出ることもありそうなので、正確な時刻に実施する必要がある処理には向いていないかもしれません。

## まとめ
プロトタイプとしてlighthouseを利用した計測を始めてみましたが、本格運用もできそうな気がしてきました！
GitHub Actionsを利用して独自のワークフローが簡単に組めることもわかったので、CI/CDにもどんどん利用していこうと思います。