感受不錯的一個FP、FCP、FID三個性能類別和組件生命週期性能的工具,做者是谷歌開發團隊的工程師Leonardo Zizzamia。 我的感受不錯,翻譯了下Readme 並PR 目前已合併入主分支。javascript
一個靈活的庫,用於測量第一個dom生成的時間(FP/FCP)、用戶最先可操做時間(fid)和組件的生命週期性能。向Google Analytics或您理想的跟蹤工具報告實際用戶測量值。html
English | 簡體中文java
Perfume 利用最新的 W3C Performance 提案 (好比 PerformanceObserver), 來測試重要的性能信息! ⚡️node
npm (www.npmjs.com/package/per…):react
npm install perfume.js --save-dev
複製代碼
你能夠直接將整個庫導入。git
import Perfume from 'perfume.js';
複製代碼
也能夠直接使用umd(Universal Module Definition)方式引入。github
import Perfume from 'node_modules/perfume.js/dist/perfume.umd.min.js';
複製代碼
FP 標記瀏覽器渲染任何在視覺上不一樣於導航前屏幕內容以內容的時間點npm
const perfume = new Perfume({
firstPaint: true
});
// Perfume.js: First Paint 1482.00 ms
複製代碼
FCP 標記的是瀏覽器渲染來自 DOM 第一位內容的時間點,該內容多是文本、圖像、SVG 甚至 <canvas>
元素。bootstrap
const perfume = new Perfume({
firstContentfulPaint: true
});
// Perfume.js: First Contentful Paint 2029.00 ms
複製代碼
FID 測量用戶首次與站點交互時(即,當他們單擊連接,點擊按鈕或使用自定義的,由JavaScript驅動的控件)到瀏覽器實際可以迴應這種互動的延時。canvas
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
複製代碼
當瀏覽器將像素渲染到屏幕時,此指標會在建立新組件後當即標記該點。
perfume.start('togglePopover');
$(element).popover('toggle');
perfume.endPaint('togglePopover');
// Perfume.js: togglePopover 10.54 ms
複製代碼
保存一段時間而且按照想要的方式打印出來
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 框架中,咱們首先配置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 {}
複製代碼
結合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>
);
}
}
複製代碼
若是想使用Perfume將你的測量結果傳遞給Google Analytics User timing,請設置選項 enable:true
以及自定義的user timing variable timingVar:"name
"。
const perfume = new Perfume({
googleAnalytics: {
enable: true,
timingVar: 'userId'
}
});
複製代碼
在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 modenpm run test
: Run test suitenpm run test:watch
: Run test suite in interactive watch modenpm run build
: Generate bundles and typingsnpm run lint
: Lints code