lighthouse の計測を毎日定時実行したくて、NOW を使ってやってみたところ、成功したり失敗したりとうまくいかなかったので、heroku と Google スプレッドシートを使ってやってみました
概要
全体の流れとしては以下のような形になります
- Google スプレッドシートでセットされた日時トリガーから、heroku へ計測用の API をキック
- Google スプレッドシートで取得用の関数を実行できるよう 5 分後にトリガーをセット
- heroku 内で lighthouse を実行し、結果をjson に吐き出す
- Google スプレッドシートで取得用の関数が実行され、heroku からjson を取得してスプレッドシートに書き出す
heroku
heroku では/tmp
フォルダは一時ファイルを格納できるらしいということで、計測を行った結果を/tmp
フォルダに json ファイルを格納し、アクセスすることで json を取得できるようにしました
実際のコードは以下に置いてます
takutakuma/lighthouse_measurement
heroku メモ
lighthouse を使うため、buildpacks にheroku-buildpack-google-chrome
を追加しています
heroku create
heroku buildpacks:set https://github.com/heroku/heroku-buildpack-nodejs\#v83
heroku buildpacks:add --index 2 https://github.com/heroku/heroku-buildpack-google-chrome.git
git push heroku master
lighthouse 実行用関数
lighthouse の実行用関数は以下のような形で作成
lighthouse のスコアを CLI だけで確認するを参考にして、追加で項目を取得しています
const lighthouse = require('lighthouse');
const chromeLauncher = require('chrome-launcher');
const perfConfig = require('lighthouse/lighthouse-core/config/perf.json');
function launchChromeAndRunLighthouse(url, opts, config = null) {
return chromeLauncher
.launch({ chromeFlags: opts.chromeFlags })
.then(chrome => {
opts.port = chrome.port;
return lighthouse(url, opts, config).then(results => {
// The gathered artifacts are typically removed as they can be quite large (~50MB+)
delete results.artifacts;
return chrome.kill().then(() => {
const scoreMap = Object.entries(results.audits).reduce(
(acc, [key, a]) => {
if (typeof a.score === 'number') {
return Object.assign({}, acc, { [key]: a.score });
}
return acc;
},
{}
);
const scoreCategories = Object.entries(
results.reportCategories
).reduce((acc, [key, a]) => {
return Object.assign({}, acc, { [a.name]: a.score });
return acc;
}, {});
return Object.assign(scoreCategories, scoreMap);
});
});
});
}
const opts = {
port: 0,
autoSelectChrome: true, // False to manually select which Chrome install.
chromeFlags: ['--headless', '--disable-gpu', '--no-sandbox']
};
// Usage:
module.exports = url => {
return launchChromeAndRunLighthouse('https://' + url, opts);
};
実行結果
単体で実行すると結果がこんな感じで取得できます
{
Performance: 30.294117647058822,
"screenshot-thumbnails": 100,
"unminified-css": 90,
"Progressive Web App": 45.45454545454545,
"consistently-interactive": 22,
Accessibility: 55.913978494623656,
redirects: 100,
"uses-rel-preload": 0,
"total-byte-weight": 89,
"dom-size": 78,
"Best Practices": 62.5,
SEO: 90,
"network-requests": 100,
"first-meaningful-paint": 44,
"estimated-input-latency": 19,
"first-interactive": 25,
"speed-index-metric": 41,
"uses-long-cache-ttl": 43,
"uses-responsive-images": 0,
"offscreen-images": 0,
"unminified-javascript": 90,
"unused-css-rules": 65,
"uses-optimized-images": 0,
"uses-request-compression": 100,
"uses-webp-images": 0,
"link-blocking-first-paint": 0,
"script-blocking-first-paint": 0
}
Google スプレッドシート
トリガー設定用関数
function setTrigger(funcName) {
// 5分後に実行
ScriptApp.newTrigger(funcName)
.timeBased()
.after(5 * 60 * 1000)
.create();
}
トリガー削除用関数
function delTrigger(funcName) {
var triggers = ScriptApp.getProjectTriggers();
for (var i = 0; i < triggers.length; i++) {
if (triggers[i].getHandlerFunction() == funcName) {
ScriptApp.deleteTrigger(triggers[i]);
}
}
}
まとめ
herokuの無料枠を使っているので、Tokyoリージョンが使えなかったり、
Performance
の値が日によって大きく変動するので、実用に耐えれているかは微妙なところですが、
毎日計測するという当初の目標は達成できたので良かったです。