Node.js使用Playwright自动化测试页面性能
作者:前端安迪
概要
对于现在的网站而言,性能的重要性不言而喻,每一家公司的网站都在追求更快地性能,更好地体验,但是,该怎么去找到影响网站速度的因素,如何优化性能,这是一个非常考验前端工程师技术功底的时刻。
但其实,现代浏览器公开了许多的性能指标,这些指标可以帮我们快速确定需要改进的内容和改进方法,今天,我想和大家介绍一种方案,使用Playwright自动化测试页面性能。
对 Playwright 不了解的同学,可以移步我的上一篇文章了解: Playwright使用指南
我们可以通过 Playwright 查询浏览器提供的各种与性能相关的 API,然后识别导致网站速度变慢的原因。比如,Chrome 浏览器提供了WebVitals 指标,这些指标包括Time to First Byte (TTFB)
、 Total BlockTime (TBT)
和 First Contentful Paint (FCP)
,这是非常好的衡量用户体验的指标,很值得我们在测试中进行监控。
接下来,给大家介绍几种常见的衡量页面性能的方案。
导航和资源加载时间 API
这个API允许你检索和页面加载时间相关的所有事件的时间,比如domComplete time
, duration
和 connectEnd
。我们可以在测试过程中使用这些指标来检测网页性能情况。
1. Performance 得分
我们可以使用Playwright定期检查页面性能,确保网页的性能不低于你设置的某个特定标准。
例如下面的这段代码,我们可以使用 Playwright 来自动化检测淘宝网的 domComplete
时间,如果它低于某一个阈值,然后会提醒我们测试用例失败,这样我们就可以及时去对页面做性能回归。
import { chromium } from 'playwright'; (async () => { const browser = await chromium.launch({ headless: true, }); const context = await browser.newContext() const page = await context.newPage() await page.goto('https://www.taobao.com/'); const navigationTimingJson = await page.evaluate(() => JSON.stringify(performance.getEntriesByType('navigation')) ) const navigationTiming = JSON.parse(navigationTimingJson) if (navigationTiming.domComplete < 2000) { console.error('ERROR: domComplete below 2 seconds') } await browser.close() })()
2. 资源加载时间 API
这个API 提供了一种可以让我们获取页面特定资源加载时间的方法,方便我们衡量页面资源加载时间。
例如,我们可以使用下面这段代码来检查淘宝网首页的webp
格式图片的加载时间。
import { chromium } from 'playwright'; (async () => { const browser = await chromium.launch({ headless: true, }); const context = await browser.newContext() const page = await context.newPage() await page.goto('https://www.taobao.com/'); const resourceTimingJson = await page.evaluate(() => JSON.stringify(window.performance.getEntriesByType('resource')) ) const resourceTiming = JSON.parse(resourceTimingJson) const logoResourceTiming = resourceTiming.find((element) => element.name.includes('.webp') ) console.log(logoResourceTiming) await browser.close() })()
页面绘制时间 API
我们可以使用页面绘制时间 API 来检索页面 First Paint (FP)
和 First Contentful Paint (FCP)
的时间。
import { chromium } from 'playwright'; (async () => { const browser = await chromium.launch({ headless: true, }); const context = await browser.newContext() const page = await context.newPage() await page.goto('https://www.taobao.com/'); const paintTimingJson = await page.evaluate(() => JSON.stringify(window.performance.getEntriesByType('paint')) ) const paintTiming = JSON.parse(paintTimingJson) console.log(paintTiming) await browser.close() })()
布局稳定性 API
这个API可以提供有关页面布局变化的信息,可以用来计算网页的 Core Web Vital Cumulative Layout Shift (CLS)
数据
import { chromium } from 'playwright'; (async () => { const browser = await chromium.launch({ headless: true, }); const context = await browser.newContext() const page = await context.newPage() await page.goto('https://www.taobao.com/'); const cummulativeLayoutShift = await page.evaluate(() => { return new Promise((resolve) => { let CLS = 0 new PerformanceObserver((l) => { const entries = l.getEntries() entries.forEach(entry => { if (!entry.hadRecentInput) { CLS += entry.value } }) resolve(CLS) }).observe({ type: 'layout-shift', buffered: true }) }) }) console.log(parseFloat(cummulativeLayoutShift)) await browser.close() })()
Long Task(长任务) API
Long Task API 会返回一个Javascript 执行列表,这些列表中的执行需要50毫秒才能完成,意味着阻塞了页面的UI线程,造成页面卡顿。我们可以用这个API来计算页面的总阻塞时间 Total Blocking Time (TBT).
例如下面这段代码,我们使用了 PerformanceObserver
来计算出页面长任务时间超过50毫秒的时间之和。
import { chromium } from 'playwright'; (async () => { const browser = await chromium.launch({ headless: true, }); const context = await browser.newContext() const page = await context.newPage() await page.goto('https://www.taobao.com/'); const totalBlockingTime = await page.evaluate(() => { return new Promise((resolve) => { let totalBlockingTime = 0 new PerformanceObserver(function (list) { const perfEntries = list.getEntries() for (const perfEntry of perfEntries) { totalBlockingTime += perfEntry.duration - 50 } resolve(totalBlockingTime) }).observe({ type: 'longtask', buffered: true }) // Resolve promise if there haven't been any long tasks setTimeout(() => resolve(totalBlockingTime), 5000) }) }) console.log(parseFloat(totalBlockingTime)) await browser.close() })()
Chrome DevTools Performance
Chrome DevTools 提供了很多非常有用的功能,我们可以充分利用起来。例如,我们可以使用Network.emulateNetworkConditions
来控制浏览器网速。
import { chromium } from 'playwright'; (async () => { const browser = await chromium.launch({ headless: true, }); const context = await browser.newContext() const page = await context.newPage() await page.goto('https://www.taobao.com/'); const context = await browser.newContext() const page = await context.newPage() await client.send('Network.enable') await client.send('Network.emulateNetworkConditions', { offline: false, downloadThroughput: (5 * 1024 * 1024) / 8, uploadThroughput: (4 * 1024 * 1024) / 8, latency: 30 ) await page.goto('https://testingbot.com/'); await browser.close() })()
以上就是Node.js使用Playwright自动化测试页面性能的详细内容,更多关于Playwright测试页面性能的资料请关注脚本之家其它相关文章!