puppeteer で Speed Index を算出

puppeteer という Headless Chrome を Node から操作するライブラリが今日発表されたので、以前、記事を書いた WebPagetest を使わずに Speed Index を算出する - kitak's blog を puppeteer でやってみた。

puppeteer の良さ

  • Chrome Developer Tools の開発チームのメンバーが開発・メンテナンスしているので安心
  • API が過不足なく揃っていて、かつ扱いやすい ( chrome-remote-interface 比 )

経緯

  • 会社の仮想環境とか実際のディスプレイがないマシンで Speed Index の計測を継続におこないたい。Synthetic Monitoring したい。Xvfb と格闘するのは嫌なので、Headless Browser を使いたい
  • Chrome の Headless サポートが発表された後に chrome-remote-interface で Headless Chrome を操作して Speed Index の算出を試みたのだけど、何か問題があって出来なかった(何でできなかったかは忘れた)
  • Headless Chrome を操作できる良さそうなライブラリ( puppeteer )が公開されたのでリトライ

Speed Index を算出するコード

こんなかんじ。

const fs = require('fs');
const puppeteer = require('puppeteer');
const speedline = require('speedline');

(async() => {
const browser = await puppeteer.launch();
const filename = 'trace.json';
const page = await browser.newPage();
try {
    await page.tracing.start({path: filename, screenshots: true});
    await page.goto('https://www.google.com'); // 計測したいサイトの URL に置き換えよ
    await page.tracing.stop();
    const results = await speedline(filename);
    console.log('Speed Index value:', results.speedIndex);
} catch (e) {
    console.error(e);
}
browser.close();
fs.unlinkSync(filename);
})();

色々

  • async/await を使っているので以前書いた記事のコードより読みやすい。特別、async/await で書くことにこだわりはないのだけど、puppeteer のリポジトリのサンプルコードが async/await で基本書かれているのでそれに倣った
  • 意識が低いのでファイル周りで同期 API を使っていたりするが、そこはもっと良くできそう
  • モバイル端末の viewport をエミュレートして計測したい場合は await page.emulate(devices['iPhone 6']) を足すとできる
  • Web クライアントサイドのパフォーマンスメトリクス — Speed Index、Paint Timing、TTI etc... ::ハブろぐ に書かれた Speed Index 以外のパフォーマンスメトリクスの計測もスクリプトを流し込めばできそうな気がする

その他、オートメーションの API も揃っていて、ServiceWorker のように Request/Response のインターセプトもできる。puppeteer、ページのスクレイピング、プリレンダリング、オートメーションと様々なシーンで利用できそうなおすすめのライブラリです。