作為前端人員肯定經(jīng)常遇到這樣的場(chǎng)景:需求剛上線,產(chǎn)品拿著手機(jī)來找你,為什么頁面打開這么慢呀,心想自己開發(fā)的時(shí)候也有注意性能問題呀,不可能會(huì)這么夸張。那沒辦法只能排查下是哪一塊影響了頁面的整體性能,打開瀏覽器控制臺(tái)一看,頁面上的這些配圖每張都非常大,心想這些配圖都這么大,頁面怎么快,那么我們有沒有辦法監(jiān)測(cè)頁面上的這些靜態(tài)資源大小,從而避免這種情況的發(fā)生。
Performance 接口可以獲取到當(dāng)前頁面中與性能相關(guān)的信息。
該對(duì)象提供許多屬性及方法可以用來測(cè)量頁面性能,這里介紹幾個(gè)用來獲取PerformanceEntry的方法:
該方法獲取一組當(dāng)前頁面已經(jīng)加載的資源PerformanceEntry對(duì)象。接收一個(gè)可選的參數(shù)options進(jìn)行過濾,options支持的屬性有name,entryType,initiatorType。
const entries = window.performance.getEntries();
該方法返回一個(gè)給定名稱和 name 和 type 屬性的PerformanceEntry對(duì)象數(shù)組,name的取值對(duì)應(yīng)到資源數(shù)據(jù)中的name字段,type取值對(duì)應(yīng)到資源數(shù)據(jù)中的entryType字段。
const entries = window.performance.getEntriesByName(name, type);
該方法返回當(dāng)前存在于給定類型的性能時(shí)間線中的對(duì)象PerformanceEntry對(duì)象數(shù)組。type取值對(duì)應(yīng)到資源數(shù)據(jù)中的entryType字段。
const entries = window.performance.getEntriesByType(type);
使用getEntriesByType獲取指定類型的性能數(shù)據(jù),performance entryType中有一個(gè)值為resource,用來獲取文檔中資源的計(jì)時(shí)信息。該類型包括有:script、link、img、css、xmlhttprequest、beacon、fetch、other等。
const resource = performance.getEntriesByType('resource')console.log('resource', resource)
這樣可以獲取到非常多關(guān)于資源加載的數(shù)據(jù):
為了方便查看,我們來稍微處理下數(shù)據(jù)
const resourceList = []const resource = performance.getEntriesByType('resource')console.log('resource', resource)resource.forEach((item) => { resourceList.push({ type: item.initiatorType, // 資源類型 name: item.name, // 資源名稱 loadTime: `${(item.duration / 1000).toFixed(3)}s`, // 資源加載時(shí)間 size: `${(item.transferSize / 1024).toFixed(0)}kb`, // 資源大小 })})
這樣對(duì)于每個(gè)資源的類型、名稱、加載時(shí)長以及大小,都非常清晰
但是有些資源的大小為什么會(huì)是0呢?以及還有很多頁面上的資源貌似沒有統(tǒng)計(jì)到,這是為啥呢?
這是因?yàn)轫撁嫔系馁Y源請(qǐng)求并不是一次性加載完的,比如一些資源的懶加載,這里就有可能會(huì)統(tǒng)計(jì)不到,或者資源大小統(tǒng)計(jì)會(huì)有問題,所以我們需要監(jiān)聽資源的動(dòng)態(tài)加載。
以上介紹的3個(gè)API都無法做到對(duì)資源動(dòng)態(tài)加載的監(jiān)聽,這里就需要用到PerformanceObserver來處理動(dòng)態(tài)加載的資源了
PerformanceObserver 主要用于監(jiān)測(cè)性能度量事件,在瀏覽器的性能時(shí)間軸記錄新的 performanceEntry 時(shí)會(huì)被通知。
通過使用 PerformanceObserver() 構(gòu)造函數(shù)我們可以創(chuàng)建并返回一個(gè)新的 PerformanceObserver 對(duì)象,從而進(jìn)行性能的監(jiān)測(cè)。
PerformanceObserver 與其它幾個(gè) Observer 類似,使用前需要先進(jìn)行實(shí)例化,然后使用 observe 監(jiān)聽相應(yīng)的事件。
function perf_observer(list, observer) { // ...}var observer = new PerformanceObserver(perf_observer);observer.observe({ entryTypes: ["resource"] });
它主要有以下實(shí)例方法:
new PerformanceObserver((list) => { list .getEntries() .filter( (entry) => entry.initiatorType === 'img' || entry.initiatorType === 'css', ) .forEach((entry) => { resourceList.push({ name: entry.name, // 資源名稱 loadTime: `${(entry.duration / 1000).toFixed(3)}s`, // 資源加載時(shí)間 type: entry.initiatorType, // 資源類型 size: `${(entry.transferSize / 1024).toFixed(0)}kb`, // 資源大小 }) console.log('--', resourceList) })}).observe({ entryTypes: ['resource'] })
這里需要注意的是,獲取類型除了img還得加上css,因?yàn)镃SS中可能會(huì)有通過url()加載的背景圖。
這樣,頁面上的圖片大小以及加載時(shí)長一目了然了
我們自己是知道問題了,但是還需要將這些信息推送給產(chǎn)品及運(yùn)營,這個(gè)可以通過企業(yè)微信提供的API來進(jìn)行操作,不滿足條件的資源將進(jìn)行推送通知:
setTimeout(() => { axios.get('http://127.0.0.1:3000/jjapi/user/pushMessage', { params: { msgtype: 'markdown', markdown: { content: ` <font color="warning">H5項(xiàng)目資源加載異常,請(qǐng)注意查看</font> 類型:<font color="comment">圖片資源大小超出限制</font> 異常數(shù)量:<font color="comment">${resourceList.length}例</font> 異常列表:<font color="comment">${resourceList.map( (item) => item.name, )}</font>`, }, }, })}, 8000)
通知如下:
這里為了避免跨域,使用nest自己包了一層,這樣就能夠及時(shí)發(fā)現(xiàn)線上配置資源是否有問題,并且這個(gè)腳本也不需要所有用戶都執(zhí)行,因?yàn)榇蠹业馁Y源都是一樣的,只需要配置特定白名單(比如開發(fā)、測(cè)試、產(chǎn)品),在頁面上線后,在進(jìn)行線上回歸的同時(shí)執(zhí)行該腳本去監(jiān)測(cè)上線配置資源是否都合理...
本文鏈接:http://www.tebozhan.com/showinfo-26-85234-0.html如何有效監(jiān)測(cè)網(wǎng)頁靜態(tài)資源大小?
聲明:本網(wǎng)頁內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com
上一篇: 過多的全局變量帶來的弊端與解決之道