概要
- Lighthouse でパフォーマンス計測
- 計測値を Datadog に送信
以上の2つを severless framework 上で定期実行する仕組みを構築していきます。またコードは TypeScript で書けるようにします。
パッケージ バージョン
本記事の執筆時点での serverless framework のバージョンは以下の通り。
$ serverless --version Framework Core: 2.41.2 Plugin: 5.0.0 SDK: 4.2.2 Components: 3.9.2
また、今回利用した npm パッケージのバージョンは以下の通り。
"chrome-aws-lambda": "^9.1.0", "datadog-metrics": "^0.9.3", "lighthouse": "^7.4.0", "puppeteer-core": "^9.1.1", "serverless-plugin-typescript": "^1.1.9", "tslib": "^2.2.0", "typescript": "^4.2.4"
Serverless Framework のセッティング
まずは、serverless framework のセッティングです。
CLI が npm パッケージとして提供されているので、global install します。
$ npm install -g serverless
プロジェクトを初期化して、クレデンシャルを登録します。ここではクレデンシャルの作成方法は割愛します。 また、autoupdate を有効にすると良いと思います。
# sls は serverless の短縮形コマンド名 $ sls init $ sls config credentials --provider provider --key KEY --secret SECRET $ sls config --autoupdate # これしないと毎度「更新バージョンがあるよ?」と聞いてくる
デプロイ、実行、ログ確認は以下のコマンド。
$sls deploy $ sls deploy -f FUNCTION_NAME # sls deploy に比べて容量制限が厳しいかも $ sls invoke -f FUNCTION_NAME $ sls invoke local -f FUNCTION_NAME $ sls logs -f FUNCTION_NAME
ひとまず、設定ファイルは以下のようにしました。ハンドラの中身は後述します。
service: SERVICE_NAME provider: name: aws region: ap-northeast-1 runtime: nodejs14.x lambdaHashingVersion: 20201221 timeout: 900 functions: audit: handler: handler.audit events: - schedule: # 定期実行 rate: rate(1 day) enabled: true
TypeScript を有効化
ハンドラの作成に入る前に、TypeScript を有効化しておきます。
prisma-labs/serverless-plugin-typescript
を利用すると、便利です。webpack の設定要らずで、デプロイ時にビルドを勝手にやってくれます。
$ npm init $ npm install --save serverless-plugin-typescript typescript
serverless.yml
に以下の2行を追記します。
plugins: - serverless-plugin-typescript
tsconfig.json は以下の通り。
{ "compilerOptions": { "lib": ["es2020", "dom"], "importHelpers": true, "module": "CommonJS", "esModuleInterop": true, "target": "es2020", "moduleResolution": "node", "declaration": false, "sourceMap": false, "removeComments": true, "allowJs": true, "rootDir": "./", "outDir": ".build" } }
handler の作成
Lambda の中身を実行していきます。
実行内容は以下の通り。
- Headless Chrome を立ち上げておく
- アプリケーションにログインしておく(認証ページを計測すると仮定)
- Lighthouse によるパフォーマンス計測
- Datadog への Metrics 送信
まずはパッケージインストールです。
$ npm i --save chrome-aws-lambda datadog-metrics lighthouse puppeteer-core tslib
次に、Lambda の中身を実装します。
import chromium from 'chrome-aws-lambda' import { Browser } from 'puppeteer-core'; import lighthouse from "lighthouse"; import metrics from "datadog-metrics"; import { URL } from "url"; const chromeFlags = [ "--headless", "--disable-gpu", "--no-sandbox", "--window-size=1080,1920", ]; const loginUrl = "ここにログインページのURL"; const auditTargetUrl = "ここに計測対象ページのURL"; metrics.init({ apiKey: 'ここに API キー', host: 'myhost', prefix: 'myapp.' }); export const audit = async () => { let browser: Browser; try { // puppeteer を利用して、ブラウザを立ち上げておく browser = await chromium.puppeteer.launch({ args: [...chromium.args, ...chromeFlags], defaultViewport: chromium.defaultViewport, timeout: 0, executablePath: await chromium.executablePath, }); // puppeteer を利用して、ログイン状態にしておく // (アプリケーションの実装に沿って適宜書き換えてください) const page = await browser.newPage(); await page.goto(loginUrl); const emailInput = await page.$("input#email"); await emailInput.type("ここにメールアドレス"); const passwordInput = await page.$("input#password"); await passwordInput.type("ここにパスワード"); const loginButton = await page.$("button#login"); await loginButton.clickAndWaitForNavigation(); // Lighthouse 実行(ここの設定内容はもっと工夫の余地があるかも) const runnerResult = await lighthouse(auditTargetUrl, { logLevel: "info", output: "html", onlyCategories: ["performance"], chromeFlags: chromeFlags, port: new URL(browser.wsEndpoint()).port, }); const { audits } = runnerResult.lhr; // スコアの抽出(必要とあらば拡張してください) const score = [ "server-response-time", "first-contentful-paint", "first-meaningful-paint", "interactive", ].forEach((key) => { // 必要に応じて丸め処理などをしてください const value = audits[key].numericValue metrics.gauge(key, value) }); await browser.close(); } catch (e) { console.error(e); await browser.close(); } };
以上。
ちなみに、serverless framework で Chrome を立ち上げるための serverless-chrome というパッケージがありました。
が、Unable to start Chrome
というエラーに見舞われ、代替案として chrome-aws-lambda
を利用することにしました。
参考リンク
- Datadog と Lighthouse を利用した WebPerf の継続的計測 | mediba Creator × Engineer Blog
- Lighthouse を実行し、Datadog に Metrics を送信する方法
- lighthouse/authenticated-pages.md at master · GoogleChrome/lighthouse
- 認証が必要なページで Lighthouse を動かす方法について
- lighthouse/docs/recipes/auth at master · GoogleChrome/lighthouse
- Puppeteer を離島して、Lighthouse を認証が必要なページで動かす方法について
- lighthouse/puppeteer.md at master · GoogleChrome/lighthouse
- Puppeteer と Lighthouse を共用する実装例