挑戰月薪30K | 前端性能優化的12 條建議(乾貨收藏)

做者:九思

你好,我是九思,來自騰訊前端技術部,擅長前端監控、工程化相關技術。此篇文章將圍繞前端性能優化中監控問題展開討論。css

首先咱們要知道,頁面打開快不快,不是在電腦或手機上的打開速度說了算,也不是測試同窗測試的結果說了算,而是真實用戶使用的時候說了算。前端

那麼如何去監控用戶真實使用時的頁面性能呢?本文將作細緻介紹(建議收藏)bootstrap

前端監控須要注意什麼?


首屏

頁面上線後,咱們最關心用戶打開頁面的速度,一般就是首屏。跨域

靜態資源

頁面加載離不開靜態資源的加載,包括 js、css、img、video、font 等,在現在盛行 SPA 的場景尤其重要,好比活動頁面會有不少圖片,咱們一般會開發一些模板,由產品/運營同窗來配置,而圖片多大合適是比較難肯定的,網速愈來愈快,你們對清晰度要求也愈來愈高,此時就能夠經過監測這些圖片的加載速度來酌情優化。瀏覽器

API 請求

數據是頁面中至關重要的元素,能夠說沒有數據,你的頁面幾乎沒有使用價值(純靜態除外)。固然這裏咱們只能粗暴的監控整個請求的總時間,純前端沒法監控各個階段時間,但這對於線上應用也很重要。性能優化

其餘測速

實際上線後,不一樣的應用可能會有不一樣的測速訴求,好比:視頻從加載到播放的時間,此時能夠自定義一些測速點,利用以前講述的打點方式來上報。網絡

如何監控靜態資源?


這塊其實仍是比較簡單的,只須要利用 PerformanceResourceTiming 便可,而且它的兼容性極高,能夠覆蓋到幾乎全部場景。框架

圖片

實際監控時,能夠分兩種場景,若是支持 performanceObserver 能夠實時監聽,不然使用定時器方式,此外須要將此代碼放到頁面最頂層,不然沒法監控到這段代碼以前的資源加載。dom

const typeList = \['script', 'link', 'img'\]; //   
 const staticTime = {};  
 const dealTime = (entries) => {  
 for (let i = 0, l = entries.length; i < l; i++) {  
 const entry = entries\[i\];  
 if (typeList.indexOf(entry.initiatorType) !== -1) {  
 staticTime\[entry.name\] = entry.connectEnd - entry.connectStart;  
 }  
 }  
 }  
 if (typeof window.PerformanceObserver === 'function') {   
 const observer = new window.PerformanceObserver((list) => {  
 dealTime(list.getEntries());  
 });  
 observer.observe({ entryTypes: \['resource'\] });  
 } else {  
 setInterval(() => {  
 const allEntries = performance.getEntriesByType('resource');  
 const entries = allEntries.slice(allEntries.length);  
 dealTime(entries);  
 }, 5000);  
 }

entry 部分數值前端性能

connectEnd: 32.63499999593478

connectStart: 32.63499999593478

decodedBodySize: 160302

domainLookupEnd: 32.63499999593478

domainLookupStart: 32.63499999593478

duration: 37.54000000481028

encodedBodySize: 23876

entryType: "resource"

fetchStart: 32.63499999593478

initiatorType: "link"

name: "https://stackpath.bootstrapcdn.com

nextHopProtocol: "h2"

redirectEnd: 0

redirectStart: 0

requestStart: 44.60999999719206

responseEnd: 70.17500000074506

responseStart: 65.40999999560881

secu reConnectionStart: 32.63499999593478

serverTiming:[]

startTime: 32.63499999593478

transferSize: 23971

workerStart: 0

圖片

API 監控


關於 API 的監控,能夠採用重寫 XHR 或者 fetch,這樣能夠適用任何的框架、請求庫。時間計算則是經過打點的方式,若是隻是固定項目監控,也能夠直接採用打點的方式。若是採用重寫的方式,不只能夠監控請求的時長,還能夠監控請求的成功失敗率。

打點最簡單的方式:

const startTime = Date.now();  
fn() // 假設這裏是同步執行  
const timeCycle = Date.now() - startTime; // fn的執行耗時

除了以上這幾點,前端監控的實操中咱們還應該考慮到上報、限流以及如何處理這些性能數據。

點擊連接查看詳情:https://ke.sifou.com/course/1...
圖片

上報


發送請求

發送請求咱們很容易想到適用 fetch / XHR,固然也可使用自動發起請求的 HTML 標籤,好比 script、link、img。上報數據雖然能夠拿來分析頁面的真實運行數據,但有一點要注意的是:不能影響當前頁面的運行或最小程度的影響。

是否能夠直接用 fetch/XHR 呢?答案是否認的,由於上報的域名和頁面的域名基本是不一樣的,因此這裏須要能夠前端跨域的方式。

說到跨域,瀏覽器的 src 屬性標籤基本均可以,到底用哪一個呢?原則上要適用對頁面影響最小的那個,諸如 Script、link 這些標籤以前有講述,他們都會對頁面的運行形成影響。

img 變成了較爲合適的方式,構造圖片打點不只不用插入DOM,只要在 JSnewImage 對象就能發起請求,並且尚未阻塞問題,在沒有js的瀏覽器環境中也能經過 img 標籤正常打點,這是其餘類型的資源請求所作不到的。

在全部圖片中1px x 1px 大小,gif 體積最小,相較 BMP/PNG,能夠節約41%/35%的網絡資源,因此適用 gif 相對是最佳選擇。

限流

頁面的性能數據,每次訪問都會有,若是你的項目 pv 有必定量級,那麼處理起來就會至關耗費資源,並且這些數據咱們最終是求平均值或者分位值,因此不必全量上報。那麼咱們能夠在上報前作一些限流處理。

更多內容


除了以上這幾點,前端監控的實操中咱們還應該考慮到如何處理這些性能數據,主要有取中位數、平均值、分位數等作法,因爲篇幅有限此處不作詳細介紹。

最後,若是這篇文章給你帶來些許有價值的理解,歡迎點贊、分享,更多內容可翻閱個人付費專欄《前端性能優化12問》。

點擊連接查看詳情:https://ke.sifou.com/course/1...
圖片

相關文章
相關標籤/搜索