如何生成含FCP、LCP指标的不同网络条件Playwright HTML性能报告
解决方法
要生成包含Web Vitals(FCP、LCP)的Playwright性能报告,需要调整现有代码的执行顺序,同时添加指标采集逻辑,并将指标整合到测试报告中。以下是完整实现步骤:
1. 修正网络节流的执行顺序
现有代码是先跳转页面再设置网络节流,这会导致页面加载过程不受节流控制。必须先启用网络节流,再执行page.goto:
test('慢3G网络下的性能测试', async ({ page }) => { // 先创建CDP会话并启用网络节流 const client = await page.context().newCDPSession(page); await client.send('Network.enable'); // 模拟慢3G:下载0.4Mbps,上传0.4Mbps,延迟2000ms(和你原来的配置一致) await client.send('Network.emulateNetworkConditions', { offline: false, downloadThroughput: (0.4 * 1024 * 1024) / 8, uploadThroughput: (0.4 * 1024 * 1024) / 8, latency: 2000, }); // 节流生效后再跳转页面 await page.goto('http://localhost:3000/', { waitUntil: 'load' }); });
2. 采集FCP、LCP等Web Vitals指标
可以通过两种方式采集指标,选一种适合你的即可:
方法一:利用Performance Observer监听事件
test('慢3G网络下的性能测试', async ({ page }) => { const client = await page.context().newCDPSession(page); await client.send('Network.enable'); await client.send('Network.emulateNetworkConditions', { offline: false, downloadThroughput: (0.4 * 1024 * 1024) / 8, uploadThroughput: (0.4 * 1024 * 1024) / 8, latency: 2000, }); // 提前监听FCP事件 const fcpPromise = page.evaluate(() => { return new Promise(resolve => { new PerformanceObserver((entryList) => { const entries = entryList.getEntriesByName('first-contentful-paint'); if (entries.length) { resolve(entries[0].startTime); } }).observe({ type: 'paint', buffered: true }); }); }); // 提前监听LCP事件 const lcpPromise = page.evaluate(() => { return new Promise(resolve => { new PerformanceObserver((entryList) => { const lastEntry = entryList.getEntries().pop(); resolve(lastEntry.startTime); }).observe({ type: 'largest-contentful-paint', buffered: true }); }); }); await page.goto('http://localhost:3000/', { waitUntil: 'load' }); const fcp = await fcpPromise; const lcp = await lcpPromise; // 打印指标,后续会自动同步到HTML报告 console.log(`FCP: ${fcp.toFixed(2)}ms`); console.log(`LCP: ${lcp.toFixed(2)}ms`); });
方法二:通过CDP直接获取性能指标
test('慢3G网络下的性能测试', async ({ page }) => { const client = await page.context().newCDPSession(page); await client.send('Network.enable'); await client.send('Network.emulateNetworkConditions', { offline: false, downloadThroughput: (0.4 * 1024 * 1024) / 8, uploadThroughput: (0.4 * 1024 * 1024) / 8, latency: 2000, }); await client.send('Performance.enable'); await page.goto('http://localhost:3000/', { waitUntil: 'load' }); const performanceMetrics = await client.send('Performance.getMetrics'); // 从返回的指标中筛选FCP和LCP(单位转成ms) const fcp = performanceMetrics.metrics.find(m => m.name === 'FirstContentfulPaint').value * 1000; const lcp = performanceMetrics.metrics.find(m => m.name === 'LargestContentfulPaint').value * 1000; console.log(`FCP: ${fcp.toFixed(2)}ms`); console.log(`LCP: ${lcp.toFixed(2)}ms`); });
3. 将指标整合到Playwright HTML报告
Playwright的HTML报告默认会捕获测试中的console.log输出,所以上面的打印内容会自动出现在报告里。如果需要更规整的展示,可以用test.info().attach将指标作为附件添加:
test('慢3G网络下的性能测试', async ({ page }, testInfo) => { const client = await page.context().newCDPSession(page); await client.send('Network.enable'); await client.send('Network.emulateNetworkConditions', { offline: false, downloadThroughput: (0.4 * 1024 * 1024) / 8, uploadThroughput: (0.4 * 1024 * 1024) / 8, latency: 2000, }); await client.send('Performance.enable'); await page.goto('http://localhost:3000/', { waitUntil: 'load' }); const performanceMetrics = await client.send('Performance.getMetrics'); const fcp = performanceMetrics.metrics.find(m => m.name === 'FirstContentfulPaint').value * 1000; const lcp = performanceMetrics.metrics.find(m => m.name === 'LargestContentfulPaint').value * 1000; // 添加指标到测试报告的附件中 await testInfo.attach('Web Vitals 指标', { body: JSON.stringify({ '首次内容绘制(FCP)': `${fcp.toFixed(2)}ms`, '最大内容绘制(LCP)': `${lcp.toFixed(2)}ms` }, null, 2), contentType: 'application/json' }); });
运行测试后,打开生成的HTML报告,对应测试用例下方会出现名为"Web Vitals 指标"的附件,点击即可查看格式化后的指标数据。
额外提示
- 可以把网络节流配置封装成函数,方便快速切换慢3G、快3G、4G等不同网络条件
- 若需要更全面的性能数据,还可以采集CLS(累积布局偏移)、FID(首次输入延迟)等其他Web Vitals指标
- 测试时尽量关闭其他占用带宽的进程,保证测试结果稳定
内容的提问来源于stack exchange,提问作者KnightCrawler
相关产品推荐
相关产品推荐

