lighthouseを定期的に計測するためにtravisなどを使う方法はあったのですが、
CIを使わずにnowを使って、計測結果をjsonで取得したいと思い色々やってみました
nowのURLにアクセスすれば、lighthouseの計測結果のjsonが取得できるようなものを作りました
ファイル構成とか
app
以下はexpress-generator
を使用して作成
services
は追加で作成
作成できたらnow
コマンドでnowにデプロイすれば、使えるはず
.
├── Dockerfile
└── app
├── app.js
├── bin
├── node_modules
├── package.json
├── public
├── routes
├── services
├── views
└── yarn.lock
Dockerfile
dockerfile は、nodeをベースに、chromeが動くようにと、日本語が一応表示できるようしたかったので、以下の記事を参考にしました
Dockerを使ってHeadless Chromeを動かしてみる
FROM node:8-slim
RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - &&\
sh -c 'echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list' &&\
apt-get update &&\
apt-get install -y google-chrome-unstable unzip
RUN mkdir /noto
ADD https://noto-website.storage.googleapis.com/pkgs/NotoSansCJKjp-hinted.zip /noto
WORKDIR /noto
RUN unzip NotoSansCJKjp-hinted.zip && \
mkdir -p /usr/share/fonts/noto && \
cp *.otf /usr/share/fonts/noto && \
chmod 644 -R /usr/share/fonts/noto/ && \
fc-cache -fv
WORKDIR /
RUN rm -rf /noto
# Install app dependencies
RUN npm i -g yarn
RUN mkdir /app
COPY ./app/package.json /app
RUN cd /app;yarn install
# Bundle app source
COPY . .
EXPOSE 3000
WORKDIR /app
CMD ["yarn", "start"]
package.json
express-generator でできた package.json に、lighthouse
,chrome-launcher
を追加
{
"name": "kanmi-lighthouse",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node ./bin/www"
},
"dependencies": {
"body-parser": "~1.18.2",
"chrome-launcher": "^0.10.2",
"cookie-parser": "~1.4.3",
"debug": "~2.6.9",
"express": "~4.15.5",
"jade": "~1.11.0",
"lighthouse": "^2.9.1",
"morgan": "~1.9.0",
"serve-favicon": "~2.4.5"
}
}
lighthouseの実行
servicesの配下にlighthouse.js
を作成
ここで、lighthouseの結果から今回必要なものだけを取得
chromeFlags
はどれか不要かも知れませんが、動いたのがこれなのでひとまずペンディング
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 => {
delete results.artifacts;
return chrome.kill().then(() =>
results.reportCategories.map(data => ({
name: data.name,
score: data.score
}))
);
});
});
}
const opts = {
port: 0,
autoSelectChrome: true, // False to manually select which Chrome install.
chromeFlags: [
'--show-paint-rects',
'--headless',
'--disable-device-emulation',
'--disable-gpu',
'--enable-logging',
'--no-sandbox'
]
};
module.exports = url => {
return launchChromeAndRunLighthouse('https://' + url, opts);
};
上記の関数をこんな感じで呼び出し(routes
フォルダに配置)
var express = require('express');
const lighthouse = require('../services/lighthouse');
var router = express.Router();
router.get('/', async function(req, res, next) {
const results = await lighthouse('qiita.com/');
res.json(results);
});
結果
URLにアクセスした際のjson はこんな感じに出力されます
Array[5][
({
"name": "Performance",
"score": 39.05882352941177
},
{
"name": "Progressive Web App",
"score": 45.45454545454545
},
{
"name": "Accessibility",
"score": 51.041666666666664
},
{
"name": "Best Practices",
"score": 62.5
},
{
"name": "SEO",
"score": 85
})
]
感想
lighthouse自体をローカルで動かすのは簡単だったけれど、Docker化してnowで動かすのに色々手間取りました
あと、nowだとアクセスしていないとFROZEN
状態になるので、定期的に動かさないと結果取得に時間がかかるのが難点だと思いました