この記事は韓国語から翻訳したものです。不十分な部分があれば、いつでもフィードバックをいただければありがたいです! (オリジナル記事, 同じく私が作成しました。)
バスハニャーンプロジェクトにLighthouse CIを導入し、Lighthouse CIサーバーを構築してみました。
導入背景
バスハニャーンサービスを開発する時、私たちのチームはいつもより速く、よりユーザーフレンドリーなサービスを作るために様々な試みと努力をします。その中で気にする指標の一つがGoogleが提供するLighthouseです。しかし、この指標はデバイスによって、特にパフォーマンスの部分でスコアが異なる場合があり、開発者が毎回修正して直接テストを回さなくてはならないという不便さがあります。 そこで今回、PRが発生したときに自動的にLighthouseの結果を生成してくれるLighthouse CIを導入することになりました。
Lighthouseとは?
Lighthouseはウェブページの品質を測定し、改善するためのオープンソースツールです。ウェブサイトのパフォーマンス、アクセシビリティ、検索エンジン最適化(SEO)、ベストプラクティス、プログレッシブウェブアプリ(PWA)の基準を監査します。Lighthouseは、ウェブページのパフォーマンスと品質を向上させるためにできることについての洞察を提供するレポートを生成します。デフォルトでは、LighthouseはChrome DevToolsパネルで利用できます。
Google Lighthouseは、Googleが開発したオープンソースツールで、ウェブページのパフォーマンス、アクセシビリティ、ベストプラクティス、SEO、PWAを測定するためにウェブページを監査します。 ウェブページのパフォーマンスと、その品質を改善するために何ができるのかについての洞察を提供するレポートを生成します。
Lighthouse CI
Lighthouse CIはLighthouseの結果をCLIで実行し、その結果をパイプラインに接続して保存し、保存された結果を比較できるようにするサービスです。
私たちはこのサービスをメインリポジトリに接続して、PRが生成されるたびにLighthouseの結果を生成、保存、比較し、結果を表示するサービスを構築する予定です。
Lighthouse CIを設定する
Lighthouse CIはGitHub Actionsで構築する予定です。特別な環境を構築する必要なくCLIで実行することができるので簡単に構築することができます。
まず、Lighthouse設定ファイルを生成します。プロジェクトのルートフォルダにlighthouserc.js
ファイルを生成して下記のように設定します。
module.exports = {
ci: {
collect: {
staticDistDir: './dist',
url: 'http://localhost/index.html',
numberOfRuns: 5,
},
upload: {
target: 'temporary-public-storage',
githubAppToken: process.env.LHCI_GITHUB_APP_TOKEN,
},
},
}
staticDistDir
はビルドされたファイルが保存されるフォルダを指定します。私たちのプロジェクトはビルド時に dist
フォルダに保存され、次のように設定しました。upload
はLighthouseの結果を保存する場所を指定します。temporary-public-storage
はGoogleが提供する一時的なストレージを使うというオプションです。
GitHub App TokenはGitHubでStatus Checkを表示するため必要なGitHub Appのトークンです。ここを参考してアプリをインストールした後、アプリのインストール完了ページで出てくるトークンを使います。
もっと詳しい設定方法はここで確認することができます。
次はGitHub Actionsでworkflowを設定します。.github/workflows/lighthouse.yml
ファイルを生成して下記のように設定します。
name: Lighthouse CI
on: [pull_request]
jobs:
lhci:
name: Generate Lighthouse Report
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- uses: actions/checkout@v3
- name: NodeJS Setup
uses: actions/setup-node@v3
with:
node-version: 16
- name: Check dependencies & build
run: |
yarn install
yarn build
- name: Run Lighthouse CI
id: step_lhci
run: yarn dlx @lhci/cli autorun
env:
LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_GITHUB_APP_TOKEN }}
私たちのサービスはyarnパッケージマネージャを使ってるので yarn
を使いました。 もし、npmを使ってるなら npm
に変更すればいいです。 また、yarn v1.x を使ってるなら yarn global add @lhci/cli
を使えばいいです。
これで基本的なCI構築は終わりました。PRを生成するたびにGoogleが提供する一時的なリポジトリに結果が保存され、一定期間その結果を確認することができます。
Lighthouseサーバーを構築する
上で言及したようにこのまま構築を完了すると、Googleが提供する一時ストレージに結果が保存され、一定期間、その結果を確認することができます。しかし、私たちはこの結果データを私たちが持っていたかったし、過去の記録も有効期限なしで持っていたかったので、私たちが所有するLightHouse CIサーバーを構築してみました。ガイドはここを参考にしました。
まず、Lighthouse CIサーバーを構築するためには、インターネットが接続されていて、Node v16以上がインストールされている必要があります。 また、SQLite、MySQL、PostgreSQLのいずれかのデータベースストレージが必要です。
バスハニャーンは無報酬の非営利団体なので、運営コスト削減のために有料サーバーを構築することはできるだけ控える必要があります。 そのため、私たちは無料でデータベースサーバーを作ることができるCloudtypeを使用しました。
サーバーはnodeが動いてインターネットが繋がっていればどんなサービスでも構いません。 DBサーバーを別に分離したため、Static page提供サービスでも十分に構築が可能です。私たちはプラットフォームを統一するため、同じようにCloudtypeを使いました。
const {createServer} = require('@lhci/server');
console.log('Starting server...');
createServer({
port: 3000,
storage: {
storageMethod: 'sql',
sqlDialect: 'postgres',
sqlConnectionUrl: process.env.DATABASE_URL
},
basicAuth: {
username: process.env.AUTH_USERNAME,
password: process.env.AUTH_PASSWORD
}
}).then(({port}) => console.log('LHCI listening on port', port));
上のように server.js
ファイルを生成して配布します。ここで、sqlConnectionUrl
にはデータベースのアドレスを入れる必要があります。 私たちはクラウドサービスを使ったので、DATABASE_URL
という環境変数を別に設定しておきました。もし、他のサービスを使う場合は、そのサービスの環境変数を参考してください。
basicAuth
にはユーザー認証のための情報が入ります。私たちはこのサービスを関係者のみ閲覧できるようにするためユーザー認証を追加しました。もし、外部にもCIサーバーを公開する場合は、このオプションを削除してください。同様にIDと非番号は環境変数で設定しました。
ドメイン接続後、サービスに接続すると、下記のようにユーザー認証を要求します。
ログインしたら次のような画面が表示されます。これでLighthouse CIサーバーの構築が完了しました。
GitHub ActionsとLighthouse CIサーバーを接続する方法
先ほど上でGitHub Actionsを使って構築したLighthouse CIは、PRを生成した後、自動でLighthouseの検査をした後、Googleの一時ストレージに結果が保存されるように設定しました。 今回は検査結果を先ほど構築した私たちのLighthouse CIサーバーに保存するように設定してみます。
先ほど生成した lighthouserc.js
ファイルを下記のように修正します。
module.exports = {
ci: {
collect: {
staticDistDir: './dist',
url: 'http://localhost/index.html',
numberOfRuns: 5,
},
upload: {
target: 'lhci',
serverBaseUrl: 'https://lighthouse.hybus.app',
token: process.env.LHCI_TOKEN,
githubAppToken: process.env.LHCI_GITHUB_APP_TOKEN,
basicAuth: {
username: process.env.LHCI_USERNAME,
password: process.env.LHCI_PASSWORD,
},
},
},
}
target
を変更することで、私たちが構築したLighthouse CIサーバーに保存するように設定しました。serverBaseUrl
には私たちが構築したLighthouse CIサーバーのアドレスが入ります。
token
はLighthouse CIサーバーへアクセスするためのトークンです。 このトークンはローカルで lhci wizard
を使ってプロジェクトを追加しながら生成することができます。下記のように lhci wizard
を実行します。
lhci wizard
を実行したら上のような画面が表示されます。上のトークン欄にはbuild tokenを入力します。
上で追加した環境変数をGitHub Actionsで使えるように実行環境に環境変数を追加します。下記のようにenv
に環境変数を追加します。
name: Lighthouse CI
on: [pull_request]
jobs:
lhci:
name: Generate Lighthouse Report
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- uses: actions/checkout@v3
- name: NodeJS Setup
uses: actions/setup-node@v3
with:
node-version: 16
- name: Check dependencies & build
run: |
yarn install
yarn build
- name: Run Lighthouse CI
id: step_lhci
run: yarn dlx @lhci/cli autorun
env:
LHCI_TOKEN: ${{ secrets.LHCI_TOKEN }}
LHCI_USERNAME: ${{ secrets.LHCI_USERNAME }}
LHCI_PASSWORD: ${{ secrets.LHCI_PASSWORD }}
LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_GITHUB_APP_TOKEN }}
- name: Post Link to Lighthouse Report
uses: thollander/actions-comment-pull-request@v2
with:
comment_tag: lighthouse
message: |
Check out your Lighthouse Report: https://lighthouse.hybus.app/app/projects/hybus-genesis-production
mode: recreate
さらに、Lighthouseの結果が生成されたら、生成された結果を確認できるようにLighthouseのリンクをPRにコメントで残す機能を追加しました。
結果
設定を終わったら、PRを開いたら、下記のようにLighthouse CIが自動で実行されることが確認できます。
また、Lighthouse CIサーバーに接続して結果を確認することができます。
既存のChrome DevToolsで使ってたUIで確認したい場合は「jump straight to the Lighthouse report」をクリックします。このボタンをクリックすると、Googleが提供してるLighthouse結果ビューアーで結果を確認することができます。
cf) 当時、Lighthouse CIサーバーでroot urlからアクセスしなかった時、Web UIが壊れる問題があります。このエラーについてGitHubにIssueを残しました。現在は解決済みです。