前端性能指标的监控,采集以及上报。用于测量第一个dom生成的时间(FP/FCP/LCP)、用户最早可操作时间(fid|tti)和组件的生命周期性能,,网络状况以及资源大小等等。向监控后台报告实际用户测量值。
一个小型的web性能监控库,它采集性能指标,如导航时间、资源时间、第一个有内容的油漆(FP/FCP)、最大的有内容油漆(LCP)、第一次输入延迟(FID)返回到您喜爱的分析工具。
Nemetrics 利用最新的 W3C Performance 提案 (比如 PerformanceObserver), 用于测量第一个dom生成的时间(FP/FCP)、LCP,用户最早可操作时间(fid|tti)和组件的生命周期性能。向监控后台报告实际用户测量值。
主角元素(Hero element)
框架、组件生命周期监控
你可以收集这些指标,并在根据ip采集世界各地深入了解你的客户如何看待你的应用程序的web性能。使用您喜欢的分析工具来可视化国家之间的数据,
下图是某个应用 印度/fetchTime/ 的数据图
这是一些数据分析的生成图
npm (https://www.npmjs.com/package/nemetric):
npm install nemetric --save-dev
import Nemetric from 'nemetric';
UMD
javascript import Nemetric from 'node_modules/nemetric/dist/nemetric.umd.min.js';
// fetchStart marks when the browser starts to fetch a resource // responseEnd is when the last byte of the response arrives fetchTime: parseFloat((navigation.responseEnd - navigation.fetchStart).toFixed(2)), // Service worker time plus response time workerTime: parseFloat( (navigation.workerStart > 0 ? navigation.responseEnd - navigation.workerStart : 0).toFixed(2), ), // Request plus response time (network only) totalTime: parseFloat((navigation.responseEnd - navigation.requestStart).toFixed(2)), // Response time only (download) downloadTime: parseFloat((navigation.responseEnd - navigation.responseStart).toFixed(2)), // Time to First Byte (TTFB) timeToFirstByte: parseFloat( (navigation.responseStart - navigation.requestStart).toFixed(2), ), // HTTP header size headerSize: parseFloat((navigation.transferSize - navigation.encodedBodySize|| 0).toFixed(2)), // Measuring DNS lookup time dnsLookupTime: parseFloat( (navigation.domainLookupEnd - navigation.domainLookupStart).toFixed(2), ), //page load time pageLoadTime:parseFloat( (navigation.loadEventEnd - navigation.startTime).toFixed(2), )
interface IAnalyticsTrackerOptions { data?: any; metricName: string; duration?: number; browser?: BrowserInfo | any; } const nemetric = new Nemetric({ navigationTiming: true, analyticsTracker: (data: IAnalyticsTrackerOptions) => { //上报到后台 request.get('/metric/measure', data) } }); // Nemetric: NavigationTiming {{'{'}} ... timeToFirstByte: 192.65 {{'}'}}
Resource Timing收集与文档相关的资源的性能指标。比如css、script、图像等等。 Nemetric帮助公开所有的PerformanceResourceTiming条目和分组数据。
const nemetric = new Nemetric({ resourceTiming: true, dataConsumption: true, analyticsTracker: (data: IAnalyticsTrackerOptions) => { //上报到后台 request.get('/metric/measure', data) } }); // Nemetric: dataConsumption { "css": 185.95, "fetch": 0, "img": 377.93, ... , "script": 8344.95 }
NetworkInformation 提供有关设备正在使用的连接与网络进行通信的信息,并提供了在连接类型更改时通知脚本的事件。NetworkInformation 接口不能被是实例化, 而是通过 Navigator 的 connection 属性进行访问。
const nemetric = new Nemetric({ networkInformation: true, analyticsTracker: (data: IAnalyticsTrackerOptions) => { //上报到后台 request.get('/metric/measure', data) } }); // Nemetric: NetworkInformation {downlink: 10, effectiveType: "4g", rtt: 100, saveData: false}
FP 标记浏览器渲染任何在视觉上不同于导航前屏幕内容之内容的时间点
const nemetric = new Nemetric({ firstPaint: true }); // Nemetric: First Paint 1482.00 ms
FCP 标记的是浏览器渲染来自 DOM 第一位内容的时间点,该内容可能是文本、图像、SVG 甚至
元素。const nemetric = new Nemetric({ firstContentfulPaint: true }); // Nemetric: First Contentful Paint 2029.00 ms
FID 测量用户首次与站点交互时(即,当他们单击链接,点击按钮或使用自定义的,由JavaScript驱动的控件)到浏览器实际能够回应这种互动的延时。
javascript const nemetric = new Nemetric({ firstInputDelay: true }); // Nemetric: First Input Delay 3.20 ms
LCP 标记的是浏览器渲染的最大的那个元素,可能是
const nemetric = new Nemetric({ largestContentfulPaint: true }); // Nemetric: Largest Contentful Paint 2029.00 ms
性能标记 (自定义时间测量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 框架,我们可以开始配置
Nemetric来收集初始化性能指标(比如 FCP,FID)。
将
nemetric.start()和
nemetric.endPaint()API用于组件的生命周期,已测量绘制组件所需要的时间。
import request from 'request'; import Nemetric from 'nemetric'; /** * 公开nemetric的装饰器接头 * 自动绑定nemetric到对象里面,只需要 * 1.在被绑定类里面声明静态变量 nemetric * 2.直接类命.nemetric就可以调用 * * @param project 项目名字 * @param needReport 是否需要上报 */ export const plugInNemetric = (project: string, needReport = true) => { return (target: Object) => { if (!Reflect.has(target, 'nemetric')) { const nemetric = new Nemetric({ firstInputDelay: true, firstContentfulPaint: true, largestContentfulPaint: true, navigationTiming: true, dataConsumption: true, networkInformation: true, analyticsTracker: (data: IAnalyticsTrackerOptions) => { //上报到后台 if (needReport) { request.post('/metric/measure', { ...data, project} }).catch(err => { console.log('nemetric report failed') }); } } }) Reflect.set(target, 'nemetric', nemetric); } } }import React from 'react';
@plugInNemetric('App',true) export default class App extends React.Component {
constructor() { // 开始测量要绘制的组件时间 App.nemetric.start('AppAfterPaint'); }
loadData = async () => { await request.get('whatever1'); await request.get('whatever2'); if(err){ App.nemetric.clear('AppAfterPaint'); } // 结束测量部件绘制时间 App.nemetric.endPaint('AppAfterPaint'); }
render() { const data = this.loadData(); return (
); } }Nemo App
{data}
在构造函数中提供给Nemetric默认选项。
const config: INemetricConfig = { // Metrics firstContentfulPaint: false, firstPaint: false, firstInputDelay: false, largestContentfulPaint: false, navigationTiming: false, networkInformation: false, dataConsumption: false, // Logging logPrefix: 'Nemetric:', logging: true, maxMeasureTime: 15000, warning: false, //默认是app端内应用 inApp: true, 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);