LoginSignup
30
15

More than 5 years have passed since last update.

Puppeteer で FirstMeaningfulPaint を取得する

Last updated at Posted at 2017-11-10

概要

  • パフォーマンスメトリクスのAPIを有効化する
  • setTimeout ループで FMP取得まで待つ

コード

npm install -S puppeteer

fmp.js
const puppeteer = require('puppeteer')

async function getPerformanceMetrics(page) {
  const { metrics } = await page._client.send('Performance.getMetrics')
  return metrics.reduce((acc, i) => ({ ...acc, [i.name]: i.value }), {})
}

async function waitForFMP(page) {
  let doneMet = null
  while (true) {
    const data = await getPerformanceMetrics(page)
    if (data.FirstMeaningfulPaint !== 0) {
      doneMet = data
      break
    }
    await new Promise(resolve => setTimeout(resolve, 300))
  }
  return doneMet
}

async function run(url) {
  const browser = await puppeteer.launch()
  const page = await browser.newPage()
  await page._client.send('Performance.enable')
  await page.goto(url)
  const m = await waitForFMP(page)
  console.log(
    `${url}: ${~~((m.FirstMeaningfulPaint - m.NavigationStart) * 1000)}ms`
  )
  browser.close()
}
;(async () => {
  await run('https://google.com')
  await run('https://qiita.com')
  await run('https://github.com')
  await run('https://twitter.com/mizchi')
  await run('https://r.nikkei.com')
  await run('https://yahoo.co.jp')
  await run('https://www.rakuten.co.jp/')
})()

ターゲットはそれっぽいサイトを適当に選びました。

$ node fmp.js
https://google.com: 669ms
https://qiita.com: 723ms
https://github.com: 1089ms
https://twitter.com/mizchi: 992ms
https://r.nikkei.com: 849ms
https://yahoo.co.jp: 618ms
https://www.rakuten.co.jp/: 452ms

async/await と object-rest-spread 使ってるのでたぶん node 8.x じゃないと動かないです。

これたぶんUnixtime で返ってて Timestamp からの差分だと思うけど自信はない。

おまけ: 取得できる内部パラメータ

今回は getPerformanceMetrics の FirstMeaningfullPaint だけ使いましたが、内部的にはこんなパラメータが取れています。

export type Metrics = {
  Timestamp: number,
  AudioHandlers: number,
  Documents: number,
  Frames: number,
  JSEventListeners: number,
  LayoutObjects: number,
  MediaKeySessions: number,
  MediaKeys: number,
  Nodes: number,
  Resources: number,
  ScriptPromises: number,
  SuspendableObjects: number,
  V8PerContextDatas: number,
  WorkerGlobalScopes: number,
  UACSSResources: number,
  LayoutCount: number,
  RecalcStyleCount: number,
  LayoutDuration: number,
  RecalcStyleDuration: number,
  ScriptDuration: number,
  TaskDuration: number,
  JSHeapUsedSize: number,
  JSHeapTotalSize: number,
  FirstMeaningfulPaint: number,
  DomContentLoaded: number,
  NavigationStart: number
}

TaskDuration がJSの実行やCSSのLayoutにかかった時間の合計で、ここらへんも参考になります。

30
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
30
15