WEB爆速の貴公子を目指して Lighthouse-ciを動かしてみる

# はじめに


***速さが足りない!!***

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445600/8c8f6c18-e04e-4aac-25b0-7b490c1c18e1.png)


という訳で、サイトの速度を改善していくために計測が必要ですよね？

定期的に計測する方法を探しているときに **[Lighthouse-ci](https://github.com/GoogleChrome/lighthouse-ci)**を見つけました。

その中でも計測結果をダッシュボードで可視化させチームでの速度改善に取り組むために

[LHCI Server](https://github.com/GoogleChrome/lighthouse-ci/blob/master/docs/server.md)について話していこうと思います。

どんなものかをざっくりと公式の画像つきで紹介します。

>LHCI Server を用意するために必要なもの

>- Node v10 LTS以降
- データベースストレージ（sqlite、mysql、またはpostgresql）

>>公式の参考画像

>>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445600/01a90738-01c4-be3a-80aa-2eaba95cc35e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445600/cbf1f8e7-f962-9956-da40-4860a72a15c8.png)

[引用元:LHCI Server](https://github.com/GoogleChrome/lighthouse-ci/blob/master/docs/server.md)

**できること**

- Lighthouseの計測結果を記録することができる
- コミット単位で計測結果を見ることができる
- 今までの計測結果をグラフとして可視化することができる
- ローカル環境や本番URLどちらも計測することができる
- 計測ごとの詳細の差分を可視化することができる


とりあえず公式をみながら手を動かしていった方がイメージつきやすいと思うのでやってみましょう。




# やることリスト

- 公式をみながらLHCI Serverを準備する
 - herokuでやってみよう
 - dockerでやってみよう
- LHCI Serverに計測するプロジェクトを登録
    - 計測のための設定ファイルを書く
- GithubActionsでpush時に計測してみる


## LHCI Serverを準備する

公式のREADMEの方にherokuとdockerでさくっと立ち上げる方法が書いてあるのでやってみましょう

下準備として下記が使えるようになってますでしょうか？参考記事と公式のドキュメントを添付しておきます。

- heroku CLI
- docker

**参考**

- [公式: heroku CLI導入](https://devcenter.heroku.com/articles/heroku-cli)
- [公式: dockerダウンロード](https://docs.docker.com/get-docker/)

どちらもデプロイするものは同じなので好きな方を選んでもらえればいいと思います。



### herokuでやってみる

こちらを利用する場合まず[heroku](https://jp.heroku.com/free)にアカウントを登録しましょう

>Heroku はアプリの構築、提供、監視、スケールに役立つクラウドプラットフォームで、アイデアを出してから運用を開始するまでのプロセスを迅速に進めることが可能です。また、インフラストラクチャの管理の問題からも解放されます。
公式から引用(https://jp.heroku.com/what#summary)

herokuを使えばいろんな言語でさくっとデプロイできますね。[Rails チュートリアル](https://railstutorial.jp/chapters/beginning?version=5.1#sec-heroku_setup)でも利用されてるやつですね。

*利用できるやつの例*

- 言語
    - Node
    - Ruby
    - Python
    - Java
    - PHP
    - Go
    - Scala
    - Clojure

- データベース
    - Redis
    - PostgreSQL

早速手を動かしましょう！

[公式のREADME](https://github.com/GoogleChrome/lighthouse-ci/blob/master/docs/recipes/heroku-server/README.md)の内容を触っていこうと思います。

- リポジトリを準備します。

```bash
# 作業ディレクトリとリポジトリの準備
mkdir lhci-heroku && cd lhci-heroku && git init
# LHCI Serverに必要なファイルを取ってきます。
curl https://raw.githubusercontent.com/GoogleChrome/lighthouse-ci/master/docs/recipes/heroku-server/package.json > package.json
curl https://raw.githubusercontent.com/GoogleChrome/lighthouse-ci/master/docs/recipes/heroku-server/server.js > server.js
# コミット
git add -A && git commit -m 'Initial commit'
```

ダウンロードしてくるファイルは下記のような内容になります。

```package.json
{
  "name": "lhci",
  "version": "1.0.0",
  "main": "server.js",
  "dependencies": {
    "@lhci/server": "0.4.x",
    "pg": "^7.12.1",
    "pg-hstore": "^2.3.3"
  }
}
```

```server.js
/**
 * @license Copyright 2019 Google Inc. All Rights Reserved.
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
 */
'use strict';

const {createServer} = require('@lhci/server');

console.log('Starting server...');
createServer({
  port: process.env.PORT,
  storage: {
    storageMethod: 'sql',
    sqlDialect: 'postgres',
    sqlConnectionSsl: true,
    sqlConnectionUrl: process.env.DATABASE_URL,
  },
}).then(({port}) => console.log('Listening on port', port));

```

sqlDialect でデータベースの種類と　sqlConnectionUrlでデータベースのURLを指定していますね。

**LHCI Serverではデータベースの接続としてURLを利用します。**

[postgresの例 公式](https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING)

```bash
postgres://{ユーザー名}:{パスワード}@{ホスト名}:{ポート番号}/{DB名}
```

さて早速herokuにデプロイしてみましょう！！

[heroku CLI](https://devcenter.heroku.com/articles/heroku-cli)をここから使用していきます。

```bash

# heroku上に新しいプロジェクトを作成します。
heroku create
# プロジェクトでpostgresqlを使えるようにします。
heroku addons:create heroku-postgresql:hobby-dev
# herokuにデプロイしてみます。
git push heroku master
# 実行確認し、デプロイされたアプリを開きます。
heroku ps:scale web=1
heroku open
```

このような画面が確認できればOKです。

![スクリーンショット 2020-08-31 3.06.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445600/0627bbf0-b314-c889-83ba-86e6f5bfa9c1.png)

なんか　**lhci wizard** とか書いてますね、このコマンドは LHCI Serverに計測したいプロジェクトを登録するのに必要なコマンドになります。

早速herokuの lhci serverにプロジェクトを登録したい方は[こちら](#計測結果を記録してみる)



### dockerでやってみる

dockerとはさくらナレッジさんの記事が個人的にわかりやすいので添付しておきます。



>Dockerは、インフラ関係やDevOps界隈で注目されている技術の一つで、Docker社が開発している、コンテナ型の仮想環境を作成、配布、実行するためのプラットフォームです。
引用元: [Docker入門（第一回）～Dockerとは何か、何が良いのか～](https://knowledge.sakura.ad.jp/13265/)


docker でLHCI Serverを動かしてみましょう。
こちらも[公式のREADME](https://github.com/GoogleChrome/lighthouse-ci/blob/master/docs/recipes/docker-server/README.md)の内容を触っていこうと思います。

Docker Hubにimageが上がっているので使っていきます。

`patrickhulce/lhci-server`

https://hub.docker.com/r/patrickhulce/lhci-server

今回は docker-compose.ymlを利用する方法で準備していきましょう

```bash
mkdir lhci-docker && cd lhci-docker && touch docker-compose.yml
```

``` docker-compose.yml
version: '3'
services:
  lhserver:
    image: patrickhulce/lhci-server
    ports:
      - '9001:9001'
    volumes:
      - lhci-data:/data
volumes:
  lhci-data:
```

`patrickhulce/lhci-server`はデフォルトだとsqliteを利用しているので　データ保存先の/data　を永続化しています。

`patrickhulce/lhci-server`中をみてみましょう

```lighthouserc.json
{
  "ci": {
    "server": {
      "port": 9001,
      "storage": {
        "storageMethod": "sql",
        "sqlDialect": "sqlite",
        "sqlDatabasePath": "/data/lhci.db"
      }
    }
  }
}

```

sqlDialect で sqlite

sqlDatabasePathで sqliteの保存先が書いてあります。登録先をheroku同様postgresなどに変更することもできます。


ローカル環境で起動してみる

```bash
docker-compose up -d
```

http://localhost:9001/ 
こちらにアクセス

このような画面になればOKです。

![スクリーンショット 2020-08-31 3.06.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445600/45b938b1-48f2-a91c-d4dc-cb0c14495fd9.png)

なんか　**lhci wizard** とか書いてますね、このコマンドは LHCI Serverに計測したいプロジェクトを登録するのに必要なコマンドになります。


# 計測結果を記録してみる

lhci serverで先ほどからデプロイ完了した後に出てくる、**lhci wizard**こちらのコマンドを使用してプロジェクトの登録から**lhci autorun**というコマンドを利用してプロジェクトを計測しlhci serverに計測結果を登録しましょう。

## プロジェクトのLHCI Serverへの登録

登録したいプロジェクトのディレクトリで作業していきましょう

```bash

# lhci serverのバージョンを確認する
curl https://{lhci serverのURL}/version # Make sure you can connect to your server.
0.x.x
```

僕の場合は `0.44` と返ってきました

```bash
# 取得したバージョンに対応した物をインストールします。
# 僕の場合だと0.44が返ってきたので...
npm install -g @lhci/cli@0.4.4
```

```bash
# lhci wizardコマンドを使用
lhci wizard
# 何個か質問がきます。
# lhci serverに新規でプロジェクトを登録します
? Which wizard do you want to run? new-project
# lhci serverのURLを登録
? What is the URL of your LHCI server? https://your-lhci-server.example.com/
# lhci serverに登録するプロジェクト名を登録
? What would you like to name the project? My Favorite Project
# プロジェクトのコードが管理されている場所　自分のソースがあるリポジトリのUR
? Where is the project's code hosted? https://github.com/GoogleChrome/lighthouse-ci
# 対象のブランチ名
? What branch is considered the repo's trunk or main branch? master
```

これらのコマンドを実行し終わると

- build token
- admin token

が出てきますのでメモしておきましょう

```bash

Created project My Favorite Project (XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)!
Use build token XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX to connect.
Use admin token XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX to manage the project.
```

この時点で確認してみると 今回僕は　testという名前でプロジェクトを登録しました。
しかしこの状態ではサイトの計測は行われていないので計測していこうと思います。

![スクリーンショット 2020-08-31 4.20.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445600/ff5ccc57-84c7-d361-49e1-01faf26b6717.png)


## プロジェクトの計測

計測のために必要な`lighthouserc.js`というファイルを書いていきましょう

```lighthouserc.js
module.exports = {
  ci: {
    upload: {
      target: 'lhci',
      serverBaseUrl: 'https://your-lhci-server-url.example.com',
      token: 'Your *build token* goes here', // could also use LHCI_TOKEN variable instead
    },
  },
};
```

今回は lhci serverに計測結果を記録するので
`target`はlhci
`serverBaseUrl` 
ここで登録したURLを記載

```bash

? What is the URL of your LHCI server? https://your-lhci-server.example.com/
```


`token`は

ここのtokenを記載

```bash

Use build token XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX to connect.
```

**この状態ではどこのURLを計測すればいいのか記載されていないため追記してみましょう**


### 静的サイトを対象に計測する時

https://github.com/GoogleChrome/lighthouse-ci/blob/master/docs/getting-started.md#modifications-for-sites-without-a-build-step

```lighthouserc.js
module.exports = {
  ci: {
    collect: {
      staticDistDir: './dist',
      url: ['/'],
    },
    upload: {
      target: 'lhci',
      serverBaseUrl: 'https://your-lhci-server-url.example.com',
      token: 'Your *build token* goes here', // could also use LHCI_TOKEN variable instead
    },
  },
};
```

`staticDistDir`に静的ファイルがある場所を選択します。
`url`に計測したいURLを記載します。

### 静的なサイトではない場合
https://github.com/GoogleChrome/lighthouse-ci/blob/master/docs/getting-started.md#modifications-for-sites-with-a-custom-server


```lighthouserc.js
module.exports = {
  ci: {
    collect: {
      startServerCommand: 'rails server -e production',
      url: ['http://localhost:3000/'],
    },
    upload: {
      target: 'lhci',
      serverBaseUrl: 'https://your-lhci-server-url.example.com',
      token: 'Your *build token* goes here', // could also use LHCI_TOKEN variable instead
    },
  },
};
```

`startServerCommand` にサーバーの起動のコマンドを入れてあげます　上記は railsの例です。
`url` に計測したいURLを記載します。

### 指定したURLで計測

本番のURLとか実在するサイトに対して行う場合は、startServerCommandは必要ないため
URL指定だけでも計測可能です。

```lighthouserc.js
module.exports = {
  ci: {
    collect: {
      url: ['URL']
    },
    upload: {
      target: 'lhci',
      serverBaseUrl: 'https://your-lhci-server-url.example.com',
      token: 'Your *build token* goes here', // could also use LHCI_TOKEN variable instead
    },
  },
};
```
#### 計測

```bash
# 計測
lhci autorun
```
デフォルトだと計測回数は３回計測されます。

計測回数を変えたい時は、

```lighthouserc.js
    collect: {
      numberOfRuns: 1,
    },
```

`numberOfRuns` に回数を指定すれば問題ないです

当たり前ですが計測回数を増やせばそれだけ計測にかかる時間は増えます

![スクリーンショット 2020-08-31 5.34.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445600/19ec6f16-82f6-1bf6-e454-628ed33fd681.png)





## Github Actionsで計測する

>GithubActionsとは
プッシュ、Issue、リリースなどのGitHubプラットフォームのイベントをトリガーとしてワークフローを起動しましょう。コミュニティが開発・保守し、ユーザが熟知・愛用しているサービスについて、対応するアクションを組み合わせて設定できます。
引用元: https://github.co.jp/features/actions

これを利用すれば好きなタイミングで自動的に計測を行ってくれますね。

今回はリポジトリpush時に作動する簡単なciファイルが、Lighthouse-ciの公式に書いてあるのでそちらを利用していきます。

https://github.com/GoogleChrome/lighthouse-ci

```.github/workflows/ci.yml
name: CI
on: [push]
jobs:
  lighthouseci:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-node@v1
      - run: npm install && npm install -g @lhci/cli@0.4.4
      - run: npm run export
      - run: lhci autorun
```

僕の場合は サンプルから　

- npm run build -> npm run export
- npm install -g @lhci/cli@0.4.x -> npm install -g @lhci/cli@0.4.4

変更しています。

**いざpush!!**

![スクリーンショット 2020-08-31 5.39.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445600/0e6a2cec-56a2-cbb0-90a4-8164d1612e9b.png)


無事CI実行できましたね


# まとめ

- Lighthouseの計測結果を記録することができる
- コミット単位で計測結果を見ることができる
- 今までの計測結果をグラフとして可視化することができる
- ローカル環境や本番URLどちらも計測することができる
- 計測ごとの詳細の差分を可視化することができる

他にも[assert](https://github.com/GoogleChrome/lighthouse-ci/blob/master/docs/getting-started.md#add-assertions)を設定したり。

[Basic認証](https://github.com/GoogleChrome/lighthouse-ci/blob/master/docs/server.md#security)を設定したりできるので色々試してみてください。

- push 時のタイミングで計測し一定を下回ったら失敗するようにしてみたり
- スケジューリングで毎日一定時間に本番のURLを計測してみたり

などいろんな使い方があるのかと思います。

また記録が保存されているデータベースの中身をみに行くと面白いです。

僕自身も使い始めたばかりなので知っている方色々教えてくださると助かります。

長い間お付き合いいただき,ありがとうございました。

いざ！WEB爆速の貴公子へと

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445600/8c8f6c18-e04e-4aac-25b0-7b490c1c18e1.png)