前兩篇文章中,咱們講了安裝和截圖,這篇咱們來說講頁面性能分析的相關體系。git
衆所周知,頁面性能優化要講起來可謂是整大條鏈路上的事情,在這裏筆者將不開展描述,後續筆者會出個全面的性能優化系列文章再進行講解。回到咱們的正題,咱們是利用 puppeteer 對頁面進行性能數據採集並分析,達到一個性能監控的效果。github
這裏筆者是用的 Web performance 收集的,畢竟是原生對吧。 GoogleChrome 推的 lighthouse 也是個不錯的工具,感興趣的同窗可自行研究 傳送門web
固然了,我們要分析的頁面在這裏不是咱自家產的,假如是自家頁面,那咱們只須要將代碼包裝成sdk,用戶訪問的時候收集真實數據,再分析便可。因此這裏主要是模擬分析第三方的頁面。在講具體操做前,咱們先來認識一下 performance,看下圖緩存
相關時間點在 timing 裏,加載的資源列表在 getEntries 裏,筆者也是根據下面這張圖來歸結相關時間節點數據的,有不對的地方同窗們幫忙指正下性能優化
因此有了下面核心代碼服務器
function performance() {
const data = {
cache: ['domainLookupStart', 'fetchStart'], // 讀取緩存時間
dns: ['domainLookupEnd', 'domainLookupStart'], // DNS 解析耗時
tcp: ['connectEnd', 'connectStart'], // TCP 鏈接耗時
req: ['responseStart', 'requestStart'], // 網絡請求耗時
res: ['responseEnd', 'responseStart'], // 數據傳輸耗時
dom: ['domContentLoadedEventStart', 'domLoading'], // DOM 解析耗時
readycb: ['domContentLoadedEventEnd', 'domContentLoadedEventStart'], // domContentLoaded回調函數耗時
fasrt: ['domComplete', 'domContentLoadedEventEnd'], // 首屏異步資源加載耗時,即domContentLoaded和load之間加載的資源,通常爲圖片加載,JS異步加載的資源
loadcb: ['loadEventEnd', 'loadEventStart'], // load回調函數耗時
ready: ['domContentLoadedEventEnd', 'fetchStart'], // DOM Ready耗時,白屏時間
load: ['loadEventEnd', 'fetchStart'] // 頁面徹底加載時間
};
const getData = {};
const performance = window.performance || window.msPerformance || window.webkitPerformance;
if (!performance || !performance.timing) {
return null;
}
const timing = performance.timing;
Object.keys(data).map(item => {
const firstParams = timing[data[item][0]];
const secondParams = timing[data[item][1]];
const value = Math.round(firstParams - secondParams);
value >= 0 && value < 36e5 && (getData[item] = value);
});
getData.resourceList = performance.getEntries();
return getData;
}
複製代碼
因此當咱們加載第三方頁面的時候,咱們插入此腳本,把數據撈出來,下面舉個🌰網絡
const browser = await puppeteer.launch({
headless: true,
args: [ '--no-sandbox', '--disable-setuid-sandbox' ],
});
const page = await browser.newPage();
await page.goto('https://juejin.im', {
waitUntil: [ 'load' ]
});
const monitorData = await page.evaluate(() => {
// 這裏就拿咱們最多見也最關心的數據,更全的看上面核心代碼圖便可
const data = {
ready: [ 'domContentLoadedEventEnd', 'fetchStart' ], // DOM Ready耗時,白屏時間
load: [ 'loadEventEnd', 'fetchStart' ] // 頁面徹底加載時間
};
const getData = {};
const performance = window.performance || window.msPerformance || window.webkitPerformance;
const timing = performance.timing;
Object.keys(data).map(item => {
const firstParams = timing[data[item][0]];
const secondParams = timing[data[item][1]];
const value = Math.round(firstParams - secondParams);
value >= 0 && value < 36e5 && (getData[item] = value);
});
getData.resourceList = performance.getEntries();
return Promise.resolve(getData);
});
console.log(monitorData);
複製代碼
拿到這些數據後,就能夠開展各自的業務的場景了,好比後臺系統上的展現監控,釘釘報警優化等等。 再複雜一點的場景可能須要模擬網絡環境,咱們須要再添加一些代碼,以下:less
const NETWORK_PRESETS = {
// 全部速度 / 8 是由於網絡速度一般以比特/秒,而 DevTools 預計吞吐量在字節/秒! (1字節 = 8比特)
GPRS: {
offline: false, // 是否鏈接
downloadThroughput: (50 * 1024) / 8, // 模擬下載速度
uploadThroughput: (20 * 1024) / 8, // 模擬上傳速度
latency: 500 // 模擬延遲(毫秒)
},
Regular2G: {
offline: false,
downloadThroughput: (250 * 1024) / 8,
uploadThroughput: (50 * 1024) / 8,
latency: 300
},
Good2G: {
offline: false,
downloadThroughput: (450 * 1024) / 8,
uploadThroughput: (150 * 1024) / 8,
latency: 150
},
Regular3G: {
offline: false,
downloadThroughput: (750 * 1024) / 8,
uploadThroughput: (250 * 1024) / 8,
latency: 100
},
Good3G: {
offline: false,
downloadThroughput: (1.5 * 1024 * 1024) / 8,
uploadThroughput: (750 * 1024) / 8,
latency: 40
},
Regular4G: {
offline: false,
downloadThroughput: (4 * 1024 * 1024) / 8,
uploadThroughput: (3 * 1024 * 1024) / 8,
latency: 20
},
DSL: {
offline: false,
downloadThroughput: (2 * 1024 * 1024) / 8,
uploadThroughput: (1 * 1024 * 1024) / 8,
latency: 5
},
WiFi: {
offline: false,
downloadThroughput: (30 * 1024 * 1024) / 8,
uploadThroughput: (15 * 1024 * 1024) / 8,
latency: 2
}
};
async function start(url, network) {
const browser = await puppeteer.launch({
headless: true,
args: [ '--no-sandbox', '--disable-setuid-sandbox' ],
});
const page = await browser.newPage();
await page.goto(url, { waitUntil: [ 'load' ]});
// 添加網絡環境
if (network !== 'default') {
// Connect to Chrome DevTools
const client = await page.target().createCDPSession();
// Set throttling property
await client.send('Network.emulateNetworkConditions', NETWORK_PRESETS[network]);
}
const monitorData = await page.evaluate(() => {
// ...同上
});
console.log(monitorData);
}
複製代碼
window.performance.getEntries()
的方式拿到的資源,不是本域下面的話,通常是拿不到資源大小的,這個是由第三方cdn或者服務器所控制的。lighthouse 是拿獲得的,因此根據各自場景,結合起來使用也是沒問題的。另外 puppeteer
自己也提供一些頁面數據在 page.metrics()
方法裏,同窗們可自行查看。最後,有其餘好工具分享的,歡迎評論區留言😯~_~dom