动态

详情 返回 返回

網站性能優化--性能指標及採集 - 动态 详情

引言

在平時工作中可能會遇到用户反饋:“哥們,你們的網站感覺很卡啊!”。這種來自用户的吐槽對前端同學可以説是直擊心靈的衝擊。此時就應該好好想想如何讓用户不再出現這樣的吐槽呢。首先就是指標化的瞭解自己的網站。

常用的衡量指標

可以結合兩張圖

第一張圖是瀏覽器加載整個頁面的時間線,第二張圖則是這個是Google力推的指標,主要從4個視覺反饋階段來描述頁面性能。

總結一下常用的性能指標

  • 白屏時間:白屏時間是指瀏覽器從響應用户輸入網址地址,到瀏覽器開始渲染內容的時間。
  • 首屏時間:首屏時間是指瀏覽器從響應用户輸入網絡地址,到首屏內容渲染完成的時間。 一般是首屏中的圖片加載完畢的時候,我們認為是首屏結束的時間點。
  • 完全加載時間:DOM Tree 構建完成後,開始加載網頁資源,資源完全加載完成後,從加載開始到此為網頁的完全加載時間。
  • 可交互時間 (TTI):用户第一次可以和界面進行交互的時間
  • 慢會話 Long Tasks:RAIL有在100毫秒內相應用户輸入的要求。如果響應超過這個時間就是慢會話

如何採集指標數據

Performance_API

PerformanceTiming中有許多指標,選取幾個比較常用的。

  • PerformanceTiming.responseStart:返回瀏覽器從服務器收到(或從本地緩存讀取)第一個字節時的Unix毫秒時間戳。這個可以用來反映服務器或者是CDN響應的指標。
  • PerformanceTiming.domInteractive:返回當前網頁DOM結構結束解析、開始加載內嵌資源時間,用户可以開始輸入交互的時間點
  • PerformanceTiming.loadEventEnd: 整個頁面加載結束的時間點

白屏時間的採集

可以用
window.performance.getEntriesByType('paint')
返回結果就是FP和FCP
image.png

首屏時間的採集

首屏時間需要從兩塊去衡量,一塊是圖片的加載,一塊是dom的渲染。
圖片的加載時間可以使用
window.performance.getEntriesByType('resource')
看一下返回的結果
image.png
需要判斷initiatorType,取出responseEnd。

dom部分則用MutationObserver來監聽dom變化。

另外考慮到是首屏,就需要配合getBoundingClientRect來判斷元素是否在首屏內。
最後將兩部分時間取較大值即可

拓展一下,如果你的首屏有其他資源會你也希望確認是否會大於圖片的加載,可以參考
不同資源的加載時間的獲取

TTI的採集

tti採集的庫使用非常簡單

import ttiPolyfill from './path/to/tti-polyfill.js';

ttiPolyfill.getFirstConsistentlyInteractive(opts).then((tti) => {
  // Use `tti` value in some way.
});

長任務的收集

const subscribeBtn = document.querySelector('#subscribe');

subscribeBtn.addEventListener('click', (event) => {
  // Event listener logic goes here...

  const lag = performance.now() - event.timeStamp;
  if (lag > 100) {
    ga('send', 'event', {
      eventCategory: 'Performance Metric'
      eventAction: 'input-latency',
      eventLabel: '#subscribe:click',
      eventValue: Math.round(lag),
      nonInteraction: true,
    });
  }
});

FPS

由於requestAnimationFrame會在每一幀渲染前被調用,所以fps的計算就依賴於他。

var frame = 0;
var allFrameCount = 0;
var lastTime = Date.now();
var lastFameTime = Date.now();
  
var loop = function () {
    var now = Date.now();
    var fs = (now - lastFameTime);
    var fps = Math.round(1000 / fs);
  
    lastFameTime = now;
    allFrameCount++;
    frame++;
  
    if (now > 1000 + lastTime) {
        //算出一秒左右的時間內總共渲染了多少幀
        var fps = Math.round((frame * 1000) / (now - lastTime));
        frame = 0;
        lastTime = now;
    };
  
    window.requestAnimationFrame(loop);
}
 
loop();

參考資料

https://www.cnblogs.com/wmhua...
https://www.jianshu.com/p/456...
https://www.cnblogs.com/coco1...

Add a new 评论

Some HTML is okay.