Perfume.js v2.1.2
A flexible library for measuring First Contentful Paint (FP/FCP), First Input Delay (FID) and components lifecycle performance. Report real user measurements to Google Analytics or your ideal tracking tool.
Why Perfume.js?
- ⏰ Latest Performance APIs for precise metrics
- 🔨 Cross browser tested
- 🚿 Filters out false positive/negative results
- 🔭 Browser tracker built-in
- 🤙 Support for async/await syntax
- 🛰 Flexible tracking tool
- ⚡️ Waste-zero ms with Idle Until Urgent strategy built-in
User-centric performance metrics
Perfume leverage the latest W3C Performance Drafts (like PerformanceObserver), for measuring performance that matters! ⚡️
- First Paint (FP)
- First Contentful Paint (FCP)
- First Input Delay (FID)
- Framework components lifecycle monitoring
Installing
npm (https://www.npmjs.com/package/perfume.js):
npm install perfume.js --save-dev
Importing library
You can import the generated bundle to use the whole library generated by this starter:
;
Additionally, you can import the transpiled modules from dist/es
in case you have a modular library:
;
Universal Module Definition:
;
Start measuring
FP)
First Paint (FP is the exact time the browser renders anything as visually different from what was on the screen before navigation, e.g. a background change after a long blank white screen time.
const perfume = firstPaint: true;// Perfume.js: First Paint 1482.00 ms
FCP)
First Contentful Paint (FCP is the exact time the browser renders the first bit of content from the DOM, which can be anything from an important image, text, or even the small SVG at the bottom of the page.
const perfume = firstContentfulPaint: true;// Perfume.js: First Contentful Paint 2029.00 ms
First Input Delay (FID)
FID measures the time from when a user first interacts with your site (i.e. when they click a link, tap on a button) to the time when the browser is actually able to respond to that interaction..
const perfume = firstInputDelay: true;// Perfume.js: First Input Delay 3.20 ms
Annotate metrics in the DevTools
Performance.mark (User Timing API) is used to create an application-defined peformance entry in the browser's performance entry buffer.
perfumestart'fibonacci';;perfume;// Perfume.js: fibonacci 0.14 ms
Component First Paint
This metric mark the point, immediately after creating a new component, when the browser renders pixels to the screen.
perfumestart'togglePopover';;perfume;// Perfume.js: togglePopover 10.54 ms
Custom Logging
Save the duration and print it out exactly the way you want it.
const perfume = logPrefix: '🍹 HayesValley.js:';perfumestart'fibonacci';;const duration = thisperfume;perfume;// 🍹 HayesValley.js: Custom logging 0.14 ms
Frameworks
Angular
Wth the Angular framework, we can start configuring Perfume to collect the initial performance metrics (eg. FCP, FID). Make sure to import the PefumeModule
at first inside the NgModule
to let the PerformanceObserver work correctly.
In a large application use the @PerfumeAfterViewInit()
decorator to monitor the rendering performance of the most complex components. Avoid using it inside a NgFor, instead focus on components that include a collection of smaller components.
The NgPerfume
service exposes all the methods and property of the perfume
instance, you can annotate component lifecycles combined with APIs calls to measure how long it takes to paint the component.
;;; @@ implements AfterViewInit data: AwesomeType; { // Start measure component time to paint thisperfumestart'AppComponentAfterPaint'; } { this; } loadAwesomeData = async { await AppApi; thisdata = AppApi; // End measure component time to paint thisperfume; } // Perfume.js config, supports AOT and DIconst PerfumeConfig = firstContentfulPaint: true firstInputDelay: true; @ {}
React
In combination with the React framework, we can start configuring Perfume to collect the initial performance metrics (eg. FCP, FID).
Use perfume.start()
and perfume.endPaint()
into a component lifecycle mixed with APIs calls to measure how long it takes to paint the component.
;; ; const perfume = firstContentfulPaint: true firstInputDelay: true; Component { // Start measure component time to paint perfumestart'AppAfterPaint'; } loadData = async { await AppApi; await AppApi; // End measure component time to paint perfume; } { const data = this; return <div> <h2>Awesome App</h2> <div>data</div> </div> ; }
Analytics
Google Analytics
To enable Perfume to send your measures to Google Analytics User timing, set the option enable:true
and a custom user timing variable timingVar:"name"
.
const perfume = googleAnalytics: enable: true timingVar: 'userId' ;
Generic analytics platform support
Configurable analytics callback to use Perfume.js with any platform.
const perfume = { myAnalyticsTool; });
Customize & Utilities
Default Options
Default options provided to Perfume.js constructor.
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;
Utilities
Perfume.js expose some methods and properties which may be useful to people extending the library.
const perfume = firstContentfulPaint: true firstInputDelay: true; // ValuesperfumefirstPaintDuration;perfumefirstContentfulPaintDuration;perfumefirstInputDelayDuration; // Aync Valuesconst durationFCP = await perfumeobserveFirstContentfulPaint;const durationFID = await perfumeobserveFirstInputDelay; // Send Custom User timing measure to Google Analyticsperfume;
Develop
npm start
: Runnpm 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
Articles
Credits and Specs
Made with ☕️ by @zizzamia and I want to thank some friends and projects for the work they did:
- Leveraging the Performance Metrics that Most Affect User Experience for documenting this new User-centric performance metrics;
- Performance Timeline Level 2 the definition of PerformanceObserver in that specification;
- The Contributors for their much appreciated Pull Requests and bug reports;
- you for the star you'll give this project 😉 and for supporting me by giving my project a try 😄
Contributors
This project exists thanks to all the people who contribute.
Backers
Thank you to all our backers! 🙏 [Become a backer]
Sponsors
Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [Become a sponsor]
Copyright and license
Code and documentation copyright 2019 Leonardo Zizzamia. Code released under the MIT license. Docs released under Creative Commons.
Team
Leonardo Zizzamia |