DIY 一個前端性能監控系統

博客鏈接:Nemo Metrics 輕量性能採集系統

Nemo近一年以來做了不少h5活動,,積累了不少優化開發流程經驗以及優化用戶加載與性能經驗。 但是每次覆盤轉化率都不高,我們不希望任何用戶流失。

  1. 用戶爲什麼會離開,是不是頁面報錯了?
  2. 是不是某些地區解析DNS,服務器資源/CDN資源加載慢?
  3. 大部分用戶打開我們的網頁都在哪些時間區間(哪些國家/地區,哪些版本,哪些手機的用戶打開用了多少秒)?
  4. 我們優化了頁面代碼,對用戶真正生效了嗎?

跟蹤這些問題,有助於我們優化頁面。

Nemetrics 利用最新的 W3C Performance 提案 (比如 PerformanceObserver), 用於測量第一個dom生成的時間(FP/FCP)、用戶最早可操作時間(fid|tti)和組件的生命週期性能。向監控後臺報告實際用戶測量值。

首次繪製 (FP)
首次內容繪製 (FCP)
首次輸入延遲 (FID)
主角元素(Hero element)
框架、組件生命週期監控
Navigation Timing

開始測量

首次繪製 (FP)

FP 標記瀏覽器渲染任何在視覺上不同於導航前屏幕內容之內容的時間點

const nemetric = new Nemetric({
  firstPaint: true
});
// Nemetric: First Paint 1482.00 ms

首次內容繪製 (FCP)

FCP 標記的是瀏覽器渲染來自 DOM 第一位內容的時間點,該內容可能是文本、圖像、SVG 甚至 <canvas> 元素。

const nemetric = new Nemetric({
  firstContentfulPaint: true
});
// Nemetric: First Contentful Paint 2029.00 ms

首次輸入延遲 (FID)

FID 測量用戶首次與站點交互時(即,當他們單擊鏈接,點擊按鈕或使用自定義的,由JavaScript驅動的控件)到瀏覽器實際能夠迴應這種互動的延時。

const nemetric = new Nemetric({
  firstInputDelay: true
});
// Nemetric: First Input Delay 3.20 ms

Navigation Timing

const nemetric = new Nemetric({
  navigation timing: true
});
Nemetric: NavigationTiming  
dnsLookupTime: 0
downloadTime: 0.69
fetchTime: 12.56
headerSize: 317
timeToFirstByte: 8.59
totalTime: 9.28
workerTime: 0

在開發者工具中標記指標

性能標記 (自定義時間測量API) 用於在瀏覽器的性能條目中創建自定義性能標記。

nemetric.start('doStuff');
doStuff(300);
nemetric.end('doStuff');
// Nemetric: doStuff 0.14 ms

組件首次渲染

當瀏覽器將像素渲染到屏幕時,此指標會在創建新組件後立即標記該點。

nemetric.start('togglePopover');
$(element).popover('toggle');
nemetric.endPaint('togglePopover');
// Nemetric: togglePopover 10.54 ms

自定義日誌記錄

保存一段時間並且按照想要的方式打印出來

const nemetric = new Nemetric({
  logPrefix: 'warren.js:'
});
nemetric.start('doStuff');
doStuff(500);
const duration = this.nemetric.end('doStuff');
nemetric.log('Custom logging', duration);
//warren.js: Custom logging 0.14 ms

React

結合React 框架,我們可以開始配置Nemetric來收集初始化性能指標(比如 FCP,FID)。

nemetric.start()nemetric.endPaint() API用於組件的生命週期,已測量繪製組件所需要的時間。

import React from 'react';
import Nemetric from 'nemetric';

import request from 'request';

const nemetric = new Nemetric({
  firstContentfulPaint: true,
  firstInputDelay: true
});

export default class App extends React.Component {

  constructor() {
    // 開始測量要繪製的組件時間
    nemetric.start('AppAfterPaint');
  }

  loadData = async () => {
    await request.get('whatever1');
    await request.get('whatever2');
    // 結束測量部件繪製時間
    nemetric.endPaint('AppAfterPaint');
  }

  render() {
    const data = this.loadData();
    return (
      <div>
        <h2>Nemo App</h2>
        <div>{data}</div>
      </div>
    );
  }
}

分析

Performance Analytics

通用分析平臺支持

Nemetric配置回調以支持任意平臺

const nemetric = new Nemetric({
  analyticsTracker: ({data,metricName, duration, browser}) => {
    navigator.sendBeacon(BI_URL,{data,metricName, duration,browser});
  })
});

自定義 & 工具集

默認選項

在構造函數中提供給Nemetric默認選項。

const options = {
  // Metrics
  firstContentfulPaint: false,
  firstPaint: false,
  firstInputDelay: false,
  // Analytics
  analyticsTracker: undefined,
  // Logging
  logPrefix: 'Nemetric:',
  logging: true,
  maxMeasureTime: 15000,
  warning: false,
  debugging: false,
  //是否在端內(針對端內做其他動作)
  inApp:true,
  //採樣率0-1
  sampleRate:1,
};

工具集

Nemetric 公開了一些方法和屬性,這些方法和屬性可能對擴展這個庫的人有用。

const nemetric = new Nemetric({
  firstContentfulPaint: true,
  firstInputDelay: true,
});

// Values
nemetric.firstPaintDuration;
nemetric.firstContentfulPaintDuration;
nemetric.firstInputDelayDuration;

// Aync Values
const durationFCP = await nemetric.observeFirstContentfulPaint;
const durationFID = await nemetric.observeFirstInputDelay;

// 將自定義用戶時間標識發送到Google Analytics
nemetric.sendTiming(metricName, durationFCP);

文章

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章