Webサイトを作っているとページの快適さの計測のためにLighthouseを利用しているという方は多いと思います。
Lighthouseの計測はどのように実行されていますか?
よくあるのはChromeの拡張機能を使った方法だと思いますが、計測するページが多くなってくるとそれなりに時間がかかってしまいます。
そこで、この記事ではLighthouseの計測をスクリプトで実行する方法をご紹介します!
この記事は、こんな人にオススメ!
・Lighthouseの計測をしている / しようとしている
・Webサイトのパフォーマンスを自動で計測したい
利用するツール・ライブラリ
- Lighthouse CLI
- npm-run-all
- rimraf
- mkdirp
計測&合否判定手順
早速ですが、スクリプトで計測と合否判定を実行する方法をまとめます。
他にLighthouse moduleを利用してjavascript内部でLighthouseを使用することもできるのですが、
利用できるオプションがCLIの方が多いのでCLIを選択しています。
初期構築
プロジェクトの作成と必要なライブラリのインストールを行います。
$ npm init
$ npm i lighthouse npm-run-all rimraf mkdirp
initの選択はすべてエンターでOKです!(使うとしても個人・社内に閉じたものになるはずなので)
npmスクリプト編集
今回はnpmスクリプトに具体的なタスクを定義していきます。
詳細は後程解説するのでまずは完成したものを
{
...
"scripts": {
"prelh": "npm run clean",
"lh": "run-p lh:*",
"postlh": "npm run report",
"lh-template": "lighthouse $npm_config_url --quiet --preset=desktop --chrome-flags=\"--headless\" --output json --output html --output-path ./reports/$npm_config_name",
"lh:yahoo": "npm run lh-template --url=https://yahoo.co.jp --name=yahoo",
"lh:google": "npm run lh-template --url=https://google.com --name=google",
"clean": "rimraf ./reports && mkdirp ./reports",
"report": "node src/report.js"
},
...
}
レポート用のスクリプトを作成
src/report.js
に以下のようなコードを実装し、lighthouseの結果を出力するようにします。
const fs = require('fs')
// 「./reports」配下のjsonファイル名を取得
const filenames = fs.readdirSync('reports').filter(it => it.endsWith(".json"))
const reports = {}
filenames.forEach(filename => {
// ファイルの内容を取得
const content = fs.readFileSync(`reports/${filename}`).toString()
// jsonで読込
const json = JSON.parse(content)
// 各種計測結果を取得(サンプルとしてperformanceのスコアを取得)
const performance = json.categories.performance.score * 100
// ファイル名からnpmスクリプトで指定した「name」部分を抽出
const name = filename.match(/(.+).report.json$/)[1]
// レポートに追加
reports[name] = {
performance
}
})
// テーブル形式で出力
console.table(reports)
実行
lh
スクリプトを実行すると以下のように計測結果が表示されます!
※一応数値はマスキング。。
$ npm run lh
┌─────────┬─────────────┐
│ (index) │ performance │
├─────────┼─────────────┤
│ google │ xx │
│ yahoo │ xx │
└─────────┴─────────────┘
また、reports/
配下に生成されるHTMLファイルを確認するとChromeの拡張機能のようなレポートを見ることもできます!
スクリプトの解説
ここまでで自動で計測ができるようになったと思うので、
ここからはスクリプトごとに内容を深堀していきます。
prelh / postlh
"prelh": "npm run clean",
"postlh": "npm run report",
npm scriptでは、スクリプト名の前にpre
やpost
を付けた命名のスクリプトを定義することで前後に実行されるスクリプトを指定できます!
ここでは、lh
の事前にclean
スクリプト・事後にreport
スクリプトを実行する定義になっています。
lh
"lh": "run-p lh:*",
このスクリプトでは、npm-run-allを利用してlh:yahoo
スクリプトとlh:google
スクリプトを並列実行しています。
run-p
の後にスクリプトを列挙することで複数のスクリプトを並列で実行できます。
また、*
をワイルドカードとして使用できるのでlh:*
のようにスクリプトを列挙することなく一括で定義することも可能です!
npm-run-allの使い方は別記事で紹介していますので、気になる方はご覧ください。
【npmスクリプトを並列実行!】npm-run-allの使い方lh-template
"lh-template": "lighthouse $npm_config_url --quiet --preset=desktop --chrome-flags=\"--headless\" --output json --output html --output-path ./reports/$npm_config_name",
このスクリプトでは、Lighthouse CLIの実行をしています。
指定してる引数・パラメータごとに解説していきます。
引数・オプション | 解説 |
$npm_config_url | ・計測対象のURLを指定しています ・実行時に --url=<URL> と指定することで、npm_config_urlに指定したURLが設定されます |
–quiet | ・実行時の処理経過等を出力しない設定です |
–preset=desktop | ・PC画面の計測をしたい場合に指定します ・スマホ画面の計測の場合は未指定でOKです |
–chrome-flags=\”–headless\” | ・chromeの動作を指定しています ・–headlessはブラウザをバックグラウンドで起動する設定です |
–output json –output html | ・出力するレポートの形式を指定しています ・複数指定すると複数の形式でレポートが出力されます |
–output-path ./reports/$npm_config_name | ・出力するレポートのファイル名を指定します ・ .reports.拡張子 は自動で設定されるのでその前の部分を指定します・実行時に --name=<画面名> と指定することで、npm_config_nameに指定した画面名が設定されます |
lh:yahoo / lh:google
"lh:yahoo": "npm run lh-template --url=https://yahoo.co.jp --name=yahoo",
"lh:google": "npm run lh-template --url=https://google.com --name=google",
このスクリプトでは先ほどのlh-templateを引数指定で実行しています。
この作りだと、計測画面を増やそうと思った時にurl
とname
だけ変えたスクリプトを追加すればよいです!
npm-run-allの仕組みを利用するためにスクリプト名はlh:xxxx
の形式にしましょう。
clean
"clean": "rimraf ./reports && mkdirp ./reports",
rimraf
はLinuxコマンドのrm
をnpmスクリプトでできるライブラリです。
mkdirp
はLinuxコマンドのmkdir
をnpmスクリプトでできるライブラリです。
なので、このスクリプトではreports
ディレクトリをまっさらな状態にするために、
ディレクトリの削除を作成を行っています。
report
"report": "node src/report.js"
最後は単純なjavascriptの実行です!
まとめ
この記事ではLighthouseの計測を自動で実行する方法をご紹介しました。
なんでも手動でやるよりもコマンド1つで勝手にやってくれた方が時間の節約になってよいですよね?
もし「他にもこんなこと自動化したいけどやり方が分からない」というものがあれば是非コメントにて教えてください!