perfume.js

repository·master·Indexed 25 days ago

https://github.com/zizzamia/perfume.js

A lightweight web performance monitoring library (version 9.4.1) for measuring user-centric performance metrics and Web Vitals. It collects field data using modern Performance APIs, providing enriched device data, Navigation Timing, and support for tracking User Journey steps and Element Timing via HTML attributes.

Tokens
6.1K
Snippets
14
Records
42
Agent score
82%

What's inside perfume.js

  1. Generate code scaffolding

    master

    Use the Angular CLI to generate new project entities.

    • Components: ng generate component component-name
    • Other types: Use ng generate <type> <name> where <type> can be directive, pipe, service, class, guard, interface, enum, or module.
    ng generate component component-name
  2. Track User Journey Steps

    master

    User Journey steps track 'system time' (time the user is blocked by the system, e.g., navigating or fetching data).

    1. Define Steps: Provide a steps object to initPerfume mapping step names to marks (start/end events) and a threshold.
    2. Mark Steps: Use markStep(stepName) to trigger the start or end of a defined step.
    3. Handle Navigation: Call trackUJNavigation() during application navigation changes to remove 'stale' steps (steps that started but never finished due to navigation).
    // 1. Defining Steps
    export const steps = {
      load_screen_A: {
        threshold: ThresholdTier.quick,
        marks: ['navigate_to_screen_A', 'loaded_screen_A'],
      },
      load_screen_B: {
        threshold: ThresholdTier.quick,
        marks: ['navigate_to_screen_B', 'loaded_screen_B'],
      },
    };
    
    initPerfume({ steps });
    
    // 2. Marking the start of a step
    markStep('navigate_to_screen_B');
    
    // 3. Handling navigation (e.g., in React)
    import { useLocation } from 'react-router-dom';
    
    const MyComponent = () => {
      const location = useLocation()
    
      React.useEffect(() => {
        trackUJNavigation();
      }, [location])
      ...
    }
  3. Import perfume.js library

    master

    You can import the library using standard ESM syntax or via the UMD bundle located in node_modules.

    ESM Import:

    import { initPerfume } from 'perfume.js';

    UMD Import:

    import { initPerfume } from 'node_modules/perfume.js/dist/perfume.umd.min.js';
    import { initPerfume } from 'perfume.js';
  4. Track Element Timing with HTML attributes

    master

    To track when specific HTML elements (images, text nodes) are displayed, add the elementtiming attribute with a unique identifier to the element. Enable this feature by setting elementTiming: true in initPerfume.

    <h1 elementtiming="elPageTitle" class="title">Perfume.js</h1>
    <img
      elementtiming="elHeroLogo"
      alt="Perfume.js logo"
      src="https://zizzamia.github.io/perfume/assets/perfume-logo-v5-0.0.png"
    />
    initPerfume({
      elementTiming: true,
      analyticsTracker: ({ metricName, data }) => {
        myAnalyticsTool.track(metricName, data);
      }
    });
    
    // Perfume.js: elPageTitle 256.00 ms
    // Perfume.js: elHeroLogo 1234.00 ms
  5. Configure Perfume.js options

    master

    The following options are available in the initPerfume configuration object:

    • resourceTiming (boolean): Enable resource timing collection.
    • elementTiming (boolean): Enable element timing collection.
    • analyticsTracker (function): Callback function receiving metric data.
    • maxMeasureTime (number): Maximum time to measure.
    • enableNavigtionTracking (boolean): Enable navigation tracking.
    const options = {
      resourceTiming: false,
      elementTiming: false,
      analyticsTracker: options => {},
      maxMeasureTime: 30000,
      enableNavigtionTracking: true,
    };
  6. Enable Resource Timing and Data Consumption tracking

    master

    By setting resourceTiming: true in the initPerfume configuration, Perfume.js collects performance metrics for document-dependent resources (CSS, scripts, images, etc.) and provides a dataConsumption object grouping usage by Kb.

    initPerfume({
      resourceTiming: true,
      analyticsTracker: ({ metricName, data }) => {
        myAnalyticsTool.track(metricName, data);
      }
    });
    // Perfume.js: dataConsumption { "css": 185.95, "fetch": 0, "img": 377.93, ... , "script": 8344.95 }
  7. Integrate with Google Analytics

    master

    You can send Perfume.js metrics to Google Analytics by using the analyticsTracker callback. Note that for cls (Cumulative Layout Shift), the value must be multiplied by 1000 to be sent as an integer.

    const metricNames = ['TTFB', 'RT', 'FCP', 'LCP', 'FID', 'CLS', 'TBT'];
    initPerfume({
      analyticsTracker: ({ attribution, metricName, data, navigatorInformation, rating, navigationType }) => {
        if (metricNames.includes(metricName)) {
          ga('send', 'event', {
            eventCategory: 'Perfume.js',
            eventAction: metricName,
            // Google Analytics metrics must be integers, so the value is rounded
            eventValue: metricName === 'cls' ? data * 1000 : data,
            eventLabel: navigatorInformation.isLowEndExperience ? 'lowEndExperience' : 'highEndExperience',
            // Use a non-interaction event to avoid affecting bounce rate
            nonInteraction: true,
          });
        }
      }
    });