如何使用Puppeteer测量TTFB(首字节时间)
Puppeteer 计算 TTFB 的实现方法
完全可以通过Puppeteer计算TTFB(首字节时间),不需要依赖官方专门封装的独立API,通过浏览器原生性能接口或者Puppeteer自带的请求/响应事件就能拿到准确数值,和Chrome DevTools网络面板显示的TTFB结果一致。
推荐实现(和DevTools数值对齐)
直接读取浏览器原生记录的导航性能指标,是最准确的实现方式,基于你现有代码修改即可:
const browser = await puppeteer.launch(launchOptions); const page = await browser.newPage(); // 注意不需要等所有页面资源加载完成,TTFB在收到响应第一个字节时就已确定 const response = await page.goto(url, { waitUntil: 'domcontentloaded' }); const { status } = response; // 从页面性能接口读取标准计时数据 const pagePerf = await page.evaluate(() => { const [navTiming] = performance.getEntriesByType('navigation'); return { // TTFB标准计算逻辑:响应开始时间 - 请求发起时间 ttfb: navTiming.responseStart - navTiming.requestStart, // 可按需提取其他性能节点做校验 requestInitiateTime: navTiming.requestStart, firstByteArriveTime: navTiming.responseStart } }); console.log(`当前页面TTFB:${pagePerf.ttfb}ms`);
通用监听方案(支持统计所有资源TTFB)
如果需要统计页面内接口、图片、JS等子资源的TTFB,或者不想注入脚本到页面上下文,可以通过Puppeteer的请求事件监听实现:
const browser = await puppeteer.launch(launchOptions); const page = await browser.newPage(); const requestRecord = new Map(); let mainFrameTTFB; // 记录请求发起时间 page.on('request', req => { // 去掉下面的判断即可统计所有资源的请求时间 if (req.isNavigationRequest() && req.frame() === page.mainFrame()) { requestRecord.set(req.url(), Date.now()); } }); // 响应头到达时(即首字节到达)计算差值 page.on('response', res => { const req = res.request(); if (req.isNavigationRequest() && req.frame() === page.mainFrame()) { const startTime = requestRecord.get(req.url()); mainFrameTTFB = Date.now() - startTime; } }); const response = await page.goto(url); const { status } = response; console.log(`主文档TTFB:${mainFrameTTFB}ms`);
注意事项
- 不要使用默认的
waitUntil: 'load'配置等待页面完全加载,会增加不必要的等待耗时,domcontentloaded时机已经足够读取到准确的TTFB数据 - 第一种性能接口方案是W3C标准定义的TTFB计算逻辑,日常统计优先使用该方案
- 第二种事件监听方案的时间计算基于Node.js侧的系统时间,和浏览器内的高精度时间存在几毫秒的误差,适合多资源批量统计场景
内容的提问来源于stack exchange,提问作者Omar Dulaimi
相关产品推荐
相关产品推荐

