How to collect performance data using Puppeteer with headless Chrome?

I’m working on a project with Puppeteer and headless Chrome. My goal is to measure the first-paint time, but I’m stuck. I’ve been checking out the Chrome DevTools Performance API and found Performance.metrics. However, when I try to use it, nothing happens.

Here’s what I’ve tried:

const browser = await puppeteer.launch();
const page = await browser.newPage();
const client = await page.target().createCDPSession();

await client.send('Performance.enable');
client.on('Performance.metrics', (data) => {
  console.log('Got metrics:', data);
});

await page.goto('https://example.com');
await page.waitForNavigation({ waitUntil: 'networkidle0' });

await browser.close();

The event listener never fires. Does anyone know how to get this working? I’d really appreciate some help figuring out how to capture those performance metrics. Thanks!

I’ve found that using the Performance Observer API can be more reliable for capturing specific metrics like first paint. Here’s an approach that’s worked well for me:

await page.evaluateOnNewDocument(() => {
  new PerformanceObserver((list) => {
    const entries = list.getEntries();
    for (const entry of entries) {
      if (entry.name === 'first-paint') {
        console.log('First Paint:', entry.startTime);
      }
    }
  }).observe({entryTypes: ['paint']});
});

await page.goto('https://example.com');

This method injects the observer into the page before navigation, ensuring you don’t miss the paint events. It’s been more consistent in my experience, especially for single-page applications.

I’ve been working on a similar project, and I found that combining Puppeteer with the Lighthouse API gives really comprehensive performance data. Here’s what worked for me:

const chromeLauncher = require('chrome-launcher');
const puppeteer = require('puppeteer');
const lighthouse = require('lighthouse');
const {URL} = require('url');

async function runLighthouseAnalysis(url) {
  const chrome = await chromeLauncher.launch({chromeFlags: ['--headless']});
  const options = {
    logLevel: 'info',
    output: 'json',
    onlyCategories: ['performance'],
    port: chrome.port,
  };
  
  const runnerResult = await lighthouse(url, options);
  const reportJson = JSON.parse(runnerResult.report);
  
  console.log('First Contentful Paint:', reportJson.audits['first-contentful-paint'].numericValue);
  console.log('First Meaningful Paint:', reportJson.audits['first-meaningful-paint'].numericValue);
  
  await chrome.kill();
}

runLighthouseAnalysis('https://example.com');

This approach gives you access to a wealth of performance metrics, including first paint times, and it’s been really reliable in my experience. Just make sure you have the necessary dependencies installed.

hey there, i had a similar issue. try using the page.metrics() function instead. it gives you a bunch of performance data without the need for CDP. something like:

const metrics = await page.metrics();
console.log(metrics);

this should give you first-paint time and other useful stuff. hope it helps!