1. 程式人生 > >如何收集常見的前端性能信息

如何收集常見的前端性能信息

設置 頁面加載 end scrip 指南 man .com 簡易 不同

前端性能指標,大多有TTFB ,首屏,首次可交互時間等

相關的文章已經有很多,細節這裏就不多說了,可參考文末資料

總體來說,需要知道瀏覽器(新的)給我們提供了 Performance API,使用這個屬性,我們可以得到一系列跟性能相關的數據

結合各個時間點的意義,我們可以計算出關鍵的耗時指標

看看下面這張圖

技術分享圖片

經過簡單的計算,可以獲取到這樣的信息

與DevTools 的Network來比較,數據是差不多的,應該能作為參考

技術分享圖片

簡單上報一下

技術分享圖片

那麽,這些個指標是怎末計算的呢,且看代碼部分,看看註釋應該就知道了

如何計算這些時間點,因人而異,各人有不同的版本,只要覺得合理,其實都是可以的

  1 <script>
  2     ;(function(window, undefined) {
  3         function addEvent(type, fn) {
  4             if (window.addEventListener) {
  5                 window.addEventListener(type, fn, false);
  6             } else {
  7                 window.attachEvent(on + type, fn);
8 } 9 } 10 11 // load 事件觸發猴再收集相關數據 12 addEvent(load, getTiming); 13 14 // 快捷入口 15 window.getTiming = getTiming; 16 17 function getTiming() { 18 // 瀏覽器支持的API 19 var performance = window.performance;
20 21 if (!performance || !performance.timing) { 22 console.log(當前瀏覽器不支持Performance Time API); 23 return; 24 } 25 26 var timing = performance.timing, 27 timings = { 28 page: [], 29 pageReport: [] 30 }; 31 32 // 設置某一項耗時統計 33 function setPageTiming(name, text, time) { 34 timings.page.push({ 35 name: name, 36 text: text, 37 time: time + ms 38 }); 39 40 timings.pageReport.push({ 41 name: name, 42 time: time + ms 43 }); 44 } 45 46 // 頁面加載仍未完成,loadEventEnd值可能為0,需要延遲處理 47 if (timing.loadEventEnd - timing.navigationStart < 0) { 48 console.log(getTiming delay); 49 setTimeout(getTiming, 1000); 50 return; 51 } 52 53 setPageTiming(redirect, 重定向, timing.redirectEnd - timing.redirectStart); 54 setPageTiming(dns, DNS解析, timing.domainLookupEnd - timing.domainLookupStart); 55 setPageTiming(tcp, TCP連接, timing.connectEnd - timing.connectStart); 56 setPageTiming(ssl, TCP-SSL連接, !timing.secureConnectionStart ? 0 : timing.connectEnd - timing.secureConnectionStart); 57 setPageTiming(ttfb, TTFB服務器返回首個字節, timing.responseStart - timing.requestStart); 58 setPageTiming(download, DOM資源下載, timing.responseEnd - timing.responseStart); 59 setPageTiming(before-parse-html, DOM解析前耗時, timing.responseEnd - timing.navigationStart); 60 setPageTiming(html-parsed, DOM解析完成, timing.domInteractive - timing.domLoading); 61 setPageTiming(dom-loaded, DOM加載完成, timing.domComplete - timing.domLoading); 62 setPageTiming(dom-content-load, DOMContentLoaded事件開始, timing.domContentLoadedEventStart - timing.navigationStart); 63 setPageTiming(dom-content-loaded, DOMContentLoaded事件結束, timing.domContentLoadedEventEnd - timing.navigationStart); 64 setPageTiming(load, Load事件開始, timing.loadEventStart - timing.navigationStart); 65 setPageTiming(loaded, Load事件結束, timing.loadEventEnd - timing.navigationStart); 66 67 // 以下兩項可以直接獲取 68 var paintTiming = { 69 first-paint: 首屏(首次繪制), 70 first-contentful-paint: 首屏(首次內容繪制) 71 }; 72 73 performance.getEntriesByType(paint).forEach(function(entry) { 74 if (paintTiming[entry.name]) { 75 setPageTiming(entry.name, paintTiming[entry.name], entry.startTime + entry.duration); 76 } 77 }); 78 79 // 以下兩項指標與需求有關,需要根據業務要求在代碼中打點統計 80 // setPageTiming(‘first-meaningful-paint‘, ‘首屏(首次有效繪制)‘, timing.domInteractive - timing.navigationStart); 81 // setPageTiming(‘time-to-interactive‘, ‘可交互時間‘, timing.domInteractive - timing.navigationStart); 82 83 // 簡易版統計上報 84 if (requestIdleCallback) { 85 requestIdleCallback(function() { 86 report(timings.pageReport); 87 }); 88 } else { 89 setTimeout(function() { 90 report(timings.pageReport); 91 }); 92 } 93 94 function report(data) { 95 data = data || []; 96 97 if (!data.length) { 98 return; 99 } 100 101 (new Image()).src = https://a.b.c/d/e?t= + (new Date()) 102 + &l= + location.href 103 + &p= + navigator.platform 104 + &net= + navigator.connection.effectiveType 105 + &u= + navigator.userAgent 106 + &times= + JSON.stringify(data); 107 } 108 109 console.table(timings.page); 110 console.log(performance.timing); 111 } 112 })(window); 113 </script>

參考資料:

以用戶為中心的性能指標

2018你應該知道的前端性能信息采集指南

Speed Matters

前端性能監控

如何收集常見的前端性能信息