Node.js使用Playwright自動(dòng)化測(cè)試頁(yè)面性能
概要
對(duì)于現(xiàn)在的網(wǎng)站而言,性能的重要性不言而喻,每一家公司的網(wǎng)站都在追求更快地性能,更好地體驗(yàn),但是,該怎么去找到影響網(wǎng)站速度的因素,如何優(yōu)化性能,這是一個(gè)非常考驗(yàn)前端工程師技術(shù)功底的時(shí)刻。
但其實(shí),現(xiàn)代瀏覽器公開(kāi)了許多的性能指標(biāo),這些指標(biāo)可以幫我們快速確定需要改進(jìn)的內(nèi)容和改進(jìn)方法,今天,我想和大家介紹一種方案,使用Playwright自動(dòng)化測(cè)試頁(yè)面性能。
對(duì) Playwright 不了解的同學(xué),可以移步我的上一篇文章了解: Playwright使用指南
我們可以通過(guò) Playwright 查詢?yōu)g覽器提供的各種與性能相關(guān)的 API,然后識(shí)別導(dǎo)致網(wǎng)站速度變慢的原因。比如,Chrome 瀏覽器提供了WebVitals 指標(biāo),這些指標(biāo)包括Time to First Byte (TTFB)、 Total BlockTime (TBT) 和 First Contentful Paint (FCP),這是非常好的衡量用戶體驗(yàn)的指標(biāo),很值得我們?cè)跍y(cè)試中進(jìn)行監(jiān)控。
接下來(lái),給大家介紹幾種常見(jiàn)的衡量頁(yè)面性能的方案。
導(dǎo)航和資源加載時(shí)間 API
這個(gè)API允許你檢索和頁(yè)面加載時(shí)間相關(guān)的所有事件的時(shí)間,比如domComplete time , duration 和 connectEnd。我們可以在測(cè)試過(guò)程中使用這些指標(biāo)來(lái)檢測(cè)網(wǎng)頁(yè)性能情況。
1. Performance 得分
我們可以使用Playwright定期檢查頁(yè)面性能,確保網(wǎng)頁(yè)的性能不低于你設(shè)置的某個(gè)特定標(biāo)準(zhǔn)。
例如下面的這段代碼,我們可以使用 Playwright 來(lái)自動(dòng)化檢測(cè)淘寶網(wǎng)的 domComplete 時(shí)間,如果它低于某一個(gè)閾值,然后會(huì)提醒我們測(cè)試用例失敗,這樣我們就可以及時(shí)去對(duì)頁(yè)面做性能回歸。
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. 資源加載時(shí)間 API
這個(gè)API 提供了一種可以讓我們獲取頁(yè)面特定資源加載時(shí)間的方法,方便我們衡量頁(yè)面資源加載時(shí)間。
例如,我們可以使用下面這段代碼來(lái)檢查淘寶網(wǎng)首頁(yè)的webp格式圖片的加載時(shí)間。
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()
})()
頁(yè)面繪制時(shí)間 API
我們可以使用頁(yè)面繪制時(shí)間 API 來(lái)檢索頁(yè)面 First Paint (FP)和 First Contentful Paint (FCP)的時(shí)間。
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()
})()
布局穩(wěn)定性 API
這個(gè)API可以提供有關(guān)頁(yè)面布局變化的信息,可以用來(lái)計(jì)算網(wǎng)頁(yè)的 Core Web Vital Cumulative Layout Shift (CLS) 數(shù)據(jù)
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(長(zhǎng)任務(wù)) API
Long Task API 會(huì)返回一個(gè)Javascript 執(zhí)行列表,這些列表中的執(zhí)行需要50毫秒才能完成,意味著阻塞了頁(yè)面的UI線程,造成頁(yè)面卡頓。我們可以用這個(gè)API來(lái)計(jì)算頁(yè)面的總阻塞時(shí)間 Total Blocking Time (TBT).
例如下面這段代碼,我們使用了 PerformanceObserver 來(lái)計(jì)算出頁(yè)面長(zhǎng)任務(wù)時(shí)間超過(guò)50毫秒的時(shí)間之和。
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 提供了很多非常有用的功能,我們可以充分利用起來(lái)。例如,我們可以使用Network.emulateNetworkConditions 來(lái)控制瀏覽器網(wǎng)速。
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自動(dòng)化測(cè)試頁(yè)面性能的詳細(xì)內(nèi)容,更多關(guān)于Playwright測(cè)試頁(yè)面性能的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- Python使用Playwright進(jìn)行API接口測(cè)試
- 基于Python Playwright進(jìn)行前端性能測(cè)試的腳本實(shí)現(xiàn)
- Playwright中Web自動(dòng)化測(cè)試的實(shí)現(xiàn)
- Python中Playwright模塊進(jìn)行自動(dòng)化測(cè)試的實(shí)現(xiàn)
- 使用Python中的Playwright制作測(cè)試視頻的實(shí)現(xiàn)步驟
- 一款強(qiáng)大的端到端測(cè)試工具Playwright介紹
- 如何使用Playwright對(duì)Java API實(shí)現(xiàn)自動(dòng)視覺(jué)測(cè)試
- 使用Playwright進(jìn)行移動(dòng)端模擬測(cè)試的實(shí)現(xiàn)
相關(guān)文章
Node實(shí)現(xiàn)搜索框進(jìn)行模糊查詢
這篇文章主要為大家詳細(xì)介紹了Node實(shí)現(xiàn)搜索框進(jìn)行模糊查詢,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-06-06
VsCode與Node.js知識(shí)點(diǎn)詳解
在本篇文章中小編給大家分享了關(guān)于VsCode與Node.js的相關(guān)知識(shí)點(diǎn)以及安裝等內(nèi)容,需要的朋友們可以參考下。2019-09-09
Node.js中的文件系統(tǒng)(file system)模塊詳解
Node.js文件系統(tǒng)模塊提供了豐富的方法,用于讀取、寫(xiě)入、操作文件和目錄,文件系統(tǒng)模塊是Node.js強(qiáng)大而靈活的一部分,為文件操作提供了方便的API,本文給大家介紹Node.js中的文件系統(tǒng)(file system)模塊,感興趣的朋友一起看看吧2023-11-11
使用NestJS開(kāi)發(fā)Node.js應(yīng)用的方法
這篇文章主要介紹了使用NestJS開(kāi)發(fā)Node.js應(yīng)用的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-12-12
ajax+node+request爬取網(wǎng)絡(luò)圖片的實(shí)例(宅男福利)
下面小編就為大家?guī)?lái)一篇ajax+node+request爬取網(wǎng)絡(luò)圖片的實(shí)例(宅男福利)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-08-08

