Node.js使用Playwright自動化測試頁面性能
概要
對于現(xiàn)在的網(wǎng)站而言,性能的重要性不言而喻,每一家公司的網(wǎng)站都在追求更快地性能,更好地體驗(yàn),但是,該怎么去找到影響網(wǎng)站速度的因素,如何優(yōu)化性能,這是一個(gè)非??简?yàn)前端工程師技術(shù)功底的時(shí)刻。
但其實(shí),現(xiàn)代瀏覽器公開了許多的性能指標(biāo),這些指標(biāo)可以幫我們快速確定需要改進(jìn)的內(nèi)容和改進(jìn)方法,今天,我想和大家介紹一種方案,使用Playwright自動化測試頁面性能。
對 Playwright 不了解的同學(xué),可以移步我的上一篇文章了解: Playwright使用指南
我們可以通過 Playwright 查詢?yōu)g覽器提供的各種與性能相關(guān)的 API,然后識別導(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),很值得我們在測試中進(jìn)行監(jiān)控。
接下來,給大家介紹幾種常見的衡量頁面性能的方案。
導(dǎo)航和資源加載時(shí)間 API
這個(gè)API允許你檢索和頁面加載時(shí)間相關(guān)的所有事件的時(shí)間,比如domComplete time , duration 和 connectEnd。我們可以在測試過程中使用這些指標(biāo)來檢測網(wǎng)頁性能情況。
1. Performance 得分
我們可以使用Playwright定期檢查頁面性能,確保網(wǎng)頁的性能不低于你設(shè)置的某個(gè)特定標(biāo)準(zhǔn)。
例如下面的這段代碼,我們可以使用 Playwright 來自動化檢測淘寶網(wǎng)的 domComplete 時(shí)間,如果它低于某一個(gè)閾值,然后會提醒我們測試用例失敗,這樣我們就可以及時(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 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 提供了一種可以讓我們獲取頁面特定資源加載時(shí)間的方法,方便我們衡量頁面資源加載時(shí)間。
例如,我們可以使用下面這段代碼來檢查淘寶網(wǎng)首頁的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()
})()
頁面繪制時(shí)間 API
我們可以使用頁面繪制時(shí)間 API 來檢索頁面 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)頁面布局變化的信息,可以用來計(jì)算網(wǎng)頁的 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(長任務(wù)) API
Long Task API 會返回一個(gè)Javascript 執(zhí)行列表,這些列表中的執(zhí)行需要50毫秒才能完成,意味著阻塞了頁面的UI線程,造成頁面卡頓。我們可以用這個(gè)API來計(jì)算頁面的總阻塞時(shí)間 Total Blocking Time (TBT).
例如下面這段代碼,我們使用了 PerformanceObserver 來計(jì)算出頁面長任務(wù)時(shí)間超過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 提供了很多非常有用的功能,我們可以充分利用起來。例如,我們可以使用Network.emulateNetworkConditions 來控制瀏覽器網(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自動化測試頁面性能的詳細(xì)內(nèi)容,更多關(guān)于Playwright測試頁面性能的資料請關(guān)注腳本之家其它相關(guān)文章!
- Python使用Playwright進(jìn)行API接口測試
- 基于Python Playwright進(jìn)行前端性能測試的腳本實(shí)現(xiàn)
- Playwright中Web自動化測試的實(shí)現(xiàn)
- Python中Playwright模塊進(jìn)行自動化測試的實(shí)現(xiàn)
- 使用Python中的Playwright制作測試視頻的實(shí)現(xiàn)步驟
- 一款強(qiáng)大的端到端測試工具Playwright介紹
- 如何使用Playwright對Java API實(shí)現(xiàn)自動視覺測試
- 使用Playwright進(jìn)行移動端模擬測試的實(shí)現(xiàn)
相關(guān)文章
node.js中module.exports與exports用法上的區(qū)別
Node.js 引入了模塊(Module)概念,一個(gè)模塊可以通過module.exports 或 exports 將函數(shù)、變量等導(dǎo)出,以使其它 JavaScript 腳本通過require() 函數(shù)引入并使用。那么node.js中module.exports與exports有什么區(qū)別呢?下面小編給大家解答下2016-09-09
nodejs子進(jìn)程child_process和cluster模塊深入解析
本文從node的單線程單進(jìn)程的理解觸發(fā),介紹了child_process模塊和cluster模塊,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09
從零開始學(xué)習(xí)Node.js系列教程之設(shè)置HTTP頭的方法示例
這篇文章主要介紹了Node.js設(shè)置HTTP頭的方法,詳細(xì)分析了常見HTTP頭的功能、原理及相關(guān)設(shè)置操作技巧,需要的朋友可以參考下2017-04-04
node.js中的console.timeEnd方法使用說明
這篇文章主要介紹了node.js中的console.timeEnd方法使用說明,本文介紹了console.timeEnd的方法說明、語法、使用實(shí)例和實(shí)現(xiàn)源碼,需要的朋友可以參考下2014-12-12
nodejs簡單實(shí)現(xiàn)操作arduino
本文給大家分享的是使用nodejs來驅(qū)動arduino,主要是基于cylonjs 和 gort,有需要的小伙伴可以參考下2016-09-09

