前端性能监控新工具 perfume

5,095 阅读4分钟

感觉不错的一个FP、FCP、FID三个性能类别和组件生命周期性能的工具,作者是谷歌开发团队的工程师Leonardo Zizzamia。 个人感觉不错,翻译了下Readme 并PR 目前已合并入主分支。

Perfume.js

NPM version
Build Status
NPM Downloads
Test Coverage
JS gzip size

一个灵活的库,用于测量第一个dom生成的时间(FP/FCP)、用户最早可操作时间(fid)和组件的生命周期性能。向Google Analytics或您理想的跟踪工具报告实际用户测量值。



English | 简体中文

Why Perfume.js?

  • ⏰ 用最新的API获取精准的性能信息
  • 🔨 跨浏览器测试
  • 🚿 过滤虚假的结果
  • 🔭 浏览器跟踪器内置
  • 🤙 支持 async/await 语法
  • 🛰 灵活的跟踪工具
  • ⚡️ 内置Idle Until Urgent策略,0 毫秒浪费

以用户为中心的性能指标

Perfume 利用最新的 W3C Performance 提案 (比如 PerformanceObserver), 来测试重要的性能信息! ⚡️

  • 首次绘制 (FP)
  • 首次内容绘制 (FCP)
  • 首次输入延迟 (FID)
  • 框架、组件生命周期监控

首次绘制和首次输入延迟

安装

npm (www.npmjs.com/package/per…):

npm install perfume.js --save-dev

引入

你可以直接将整个库导入。

import Perfume from 'perfume.js';

也可以直接使用umd(Universal Module Definition)方式引入。

import Perfume from 'node_modules/perfume.js/dist/perfume.umd.min.js';

开始测量

首次绘制 (FP)

FP 标记浏览器渲染任何在视觉上不同于导航前屏幕内容之内容的时间点

const perfume = new Perfume({
  firstPaint: true
});
// Perfume.js: First Paint 1482.00 ms

首次内容绘制 (FCP)

FCP 标记的是浏览器渲染来自 DOM 第一位内容的时间点,该内容可能是文本、图像、SVG 甚至 <canvas> 元素。

const perfume = new Perfume({
  firstContentfulPaint: true
});
// Perfume.js: First Contentful Paint 2029.00 ms

首次输入延迟 (FID)

FID 测量用户首次与站点交互时(即,当他们单击链接,点击按钮或使用自定义的,由JavaScript驱动的控件)到浏览器实际能够回应这种互动的延时。

const perfume = new Perfume({
  firstInputDelay: true
});
// Perfume.js: First Input Delay 3.20 ms

在开发者工具中标记指标

性能标记 (自定义时间测量API ) 用于在浏览器的性能条目中创建自定义性能标记。

perfume.start('fibonacci');
fibonacci(400);
perfume.end('fibonacci');
// Perfume.js: fibonacci 0.14 ms

Performance Mark

组件首次渲染

当浏览器将像素渲染到屏幕时,此指标会在创建新组件后立即标记该点。

perfume.start('togglePopover');
$(element).popover('toggle');
perfume.endPaint('togglePopover');
// Perfume.js: togglePopover 10.54 ms

Performance

自定义日志记录

保存一段时间并且按照想要的方式打印出来

const perfume = new Perfume({
  logPrefix: '🍹 HayesValley.js:'
});
perfume.start('fibonacci');
fibonacci(400);
const duration = this.perfume.end('fibonacci');
perfume.log('Custom logging', duration);
// 🍹 HayesValley.js: Custom logging 0.14 ms

框架

Angular

在 Angular 框架中,我们首先配置Perfume来收集初始化性能指标(比如 FCP,FID),首先确保在NgModule中引入PefumeModule,使PerformanceObserver能正常工作。

在大型应用中使用@PerfumeAfterViewInit()装饰器来监听复杂组件的渲染性能,避免在NgFor中使用它,应该关注包含较小组件集合的组件。

NgPerfume服务公开了所有的Perfume实例的方法和属性,您可以对组件的生命周期进行标记,并结合APIs来监测组件绘制所需要的时间。

import { NgPerfume, PerfumeModule, PerfumeAfterViewInit } from 'perfume.js/angular';
import { AppComponent } from './app.component';
import { AppApi } from './app-api';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.less'],
})
@PerfumeAfterViewInit('AppComponent')
export class AppComponent implements AfterViewInit {
  data: AwesomeType;

  constructor(public perfume: NgPerfume) {
    // 开始测量要绘制的组件时间
    this.perfume.start('AppComponentAfterPaint');
  }

  ngAfterViewInit() {
    this.loadAwesomeData();
  }

  loadAwesomeData = async () => {
    await AppApi.loadAmazingData();
    this.data = AppApi.loadAwesomeData();
    // 结束测量部件绘制时间
    this.perfume.endPaint('AppComponentAfterPaint');
  }
}

// Perfume.js config, supports AOT and DI
export const PerfumeConfig = {
  firstContentfulPaint: true,
  firstInputDelay: true,
};

@NgModule({
  declarations: [AppComponent],
  imports: [PerfumeModule.forRoot(PerfumeConfig), BrowserModule],
  bootstrap: [AppComponent],
})
export class AppModule {}

Angular Performance Decorator

React

结合React 框架,我们可以开始配置Perfume来收集初始化性能指标(比如 FCP,FID)。

perfume.start()perfume.endPaint() API用于组件的生命周期,已测量绘制组件所需要的时间。

import React from 'react';
import Perfume from 'perfume.js';

import { AppApi } from './AppApi';

const perfume = new Perfume({
  firstContentfulPaint: true,
  firstInputDelay: true
});

export default class App extends React.Component {

  constructor() {
    // 开始测量要绘制的组件时间
    perfume.start('AppAfterPaint');
  }

  loadData = async () => {
    await AppApi.loadAmazingData();
    await AppApi.loadAwesomeData();
    // 结束测量部件绘制时间
    perfume.endPaint('AppAfterPaint');
  }

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

分析

Google Analytics

如果想使用Perfume将你的测量结果传递给Google Analytics User timing,请设置选项 enable:true 以及自定义的user timing variable timingVar:"name"。

const perfume = new Perfume({
  googleAnalytics: {
    enable: true,
    timingVar: 'userId'
  }
});

Performance Analytics

通用分析平台支持

Perfume.js配置回调以支持任意平台

const perfume = new Perfume({
  analyticsTracker: (metricName, duration, browser) => {
    myAnalyticsTool.track(metricName, duration, browser.name, browser.os);
  })
});

自定义 & 工具集

默认选项

在构造函数中提供给Perfume.js默认选项。

const options = {
  // Metrics
  firstContentfulPaint: false,
  firstPaint: false,
  firstInputDelay: false,
  // Analytics
  analyticsTracker: undefined,
  browserTracker: false,
  googleAnalytics: {
    enable: false,
    timingVar: 'name',
  },
  // Logging
  logPrefix: 'Perfume.js:',
  logging: true,
  maxMeasureTime: 15000,
  warning: false,
  debugging: false,
};

工具集

Perfume.js 公开了一些方法和属性,这些方法和属性可能对扩展这个库的人有用。

const perfume = new Perfume({
  firstContentfulPaint: true,
  firstInputDelay: true,
});

// Values
perfume.firstPaintDuration;
perfume.firstContentfulPaintDuration;
perfume.firstInputDelayDuration;

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

// 将自定义用户时间标识发送到Google Analytics
perfume.sendTiming(metricName, durationFCP);

开发

  • npm start: Run npm run build in watch mode
  • npm run test: Run test suite
  • npm run test:watch: Run test suite in interactive watch mode
  • npm run build: Generate bundles and typings
  • npm run lint: Lints code

文章