|
| 1 | +# Analytics Perfume.js Example - Agent Instructions |
| 2 | + |
| 3 | +This is a React example demonstrating how to integrate [Perfume.js](https://github.com/Zizzamia/perfume.js/) (web performance monitoring) with the [Analytics](https://github.com/DavidWells/analytics) library to automatically track and report performance metrics to multiple analytics providers. |
| 4 | + |
| 5 | +## Quick Start |
| 6 | + |
| 7 | +- **Start development**: `npm start` (hot reload on http://localhost:3000) |
| 8 | +- **Build for production**: `npm build` |
| 9 | +- **Run tests**: `npm test` |
| 10 | +- **Deploy to Netlify**: `npm deploy` |
| 11 | + |
| 12 | +## Project Structure & Purpose |
| 13 | + |
| 14 | +This is an **example/demo app**, not a library. The key goal is to demonstrate the pattern: |
| 15 | + |
| 16 | +``` |
| 17 | +src/ |
| 18 | +├── App.js # Main app - initializes analytics with perfume.js plugin |
| 19 | +├── plugins/ |
| 20 | +│ ├── perfume.js # Perfume.js integration plugin (tracks Web Vitals) |
| 21 | +│ └── custom.js # Simple example of a custom analytics plugin |
| 22 | +└── index.js # React entry point |
| 23 | +``` |
| 24 | + |
| 25 | +## Core Concepts & Patterns |
| 26 | + |
| 27 | +### Analytics Initialization (src/App.js) |
| 28 | + |
| 29 | +The app initializes a centralized `analytics` instance with multiple plugins: |
| 30 | + |
| 31 | +```javascript |
| 32 | +const analytics = Analytics({ |
| 33 | + app: 'my-app', |
| 34 | + plugins: [ |
| 35 | + { name: 'test-plugin', track: ({ payload }) => { ... } }, |
| 36 | + customAnalyticsPlugin, |
| 37 | + googleAnalytics({ trackingId: '...' }), |
| 38 | + perfumePlugin({ category: 'perf', perfume: Perfume }) |
| 39 | + ] |
| 40 | +}) |
| 41 | +``` |
| 42 | + |
| 43 | +**Key pattern**: Plugins are composed together. When `analytics.track()` is called, all plugins receive the event. |
| 44 | + |
| 45 | +### Plugin Architecture (src/plugins/) |
| 46 | + |
| 47 | +Plugins follow this interface: |
| 48 | + |
| 49 | +```javascript |
| 50 | +{ |
| 51 | + name: 'plugin-name', // Required: unique identifier |
| 52 | + track: ({ payload }) => { ... } // Track events |
| 53 | + initialize: ({ instance, config }) => {} // Optional: initialization hook |
| 54 | +} |
| 55 | +``` |
| 56 | + |
| 57 | +**Perfume.js plugin (`perfume.js`)**: Automatically tracks Web Vitals (FP, FCP, LCP, FID, CLS, TBT) and forwards them through analytics to all attached providers. |
| 58 | + |
| 59 | +**Custom plugin (`custom.js`)**: Simple logger example - shows minimal plugin implementation. |
| 60 | + |
| 61 | +### Performance Metrics Tracked |
| 62 | + |
| 63 | +Perfume.js monitors Core Web Vitals: |
| 64 | +- **FP** (First Paint) |
| 65 | +- **FCP** (First Contentful Paint) |
| 66 | +- **LCP** (Largest Contentful Paint) |
| 67 | +- **FID** (First Input Delay) |
| 68 | +- **CLS** (Cumulative Layout Shift) |
| 69 | +- **TBT** (Total Blocking Time) |
| 70 | + |
| 71 | +These are categorized as `lowEndExperience` or `highEndExperience` for segmentation. |
| 72 | + |
| 73 | +## Common Tasks |
| 74 | + |
| 75 | +### Add a new analytics provider |
| 76 | + |
| 77 | +1. Install the provider plugin: `npm install @analytics/[provider-name]` |
| 78 | +2. Add to the `plugins` array in `App.js`: |
| 79 | + ```javascript |
| 80 | + providerName({ config: 'values' }) |
| 81 | + ``` |
| 82 | +3. The provider automatically receives all tracked events (including perfume.js metrics) |
| 83 | + |
| 84 | +### Create a custom analytics plugin |
| 85 | + |
| 86 | +Create a new file in `src/plugins/` following the plugin interface: |
| 87 | +- Minimal: just need `name` and `track` function |
| 88 | +- Advanced: add `initialize` hook for setup |
| 89 | +- Plugin receives all analytics events via the `track` callback |
| 90 | + |
| 91 | +### Debug what's being tracked |
| 92 | + |
| 93 | +Open browser DevTools console: |
| 94 | +- The `test-plugin` in App.js logs all events to console |
| 95 | +- Each plugin sees the full `payload` with event name, properties, and metadata |
| 96 | + |
| 97 | +### Modify what perfume.js tracks |
| 98 | + |
| 99 | +Edit `src/plugins/perfume.js`: |
| 100 | +- `metricNames` array: which metrics to report |
| 101 | +- The `analyticsTracker` callback: customize how metrics are formatted and sent |
| 102 | +- Note: Metrics are scaled for Google Analytics (integers) - adjust per provider |
| 103 | + |
| 104 | +## Design Decisions |
| 105 | + |
| 106 | +- **Centralized analytics instance** in `App.js`: All tracking goes through one place |
| 107 | +- **Plugin composition**: Decoupled providers - add/remove without changing core logic |
| 108 | +- **Non-interaction events**: Perfume metrics don't affect bounce rate in GA |
| 109 | +- **Value scaling**: CLS values multiplied by 1000 for GA (which requires integers) |
| 110 | +- **Device experience segmentation**: Metrics tagged as `lowEndExperience` or `highEndExperience` |
| 111 | + |
| 112 | +## Related Resources |
| 113 | + |
| 114 | +- [Live example app](https://analytics-perfumejs-example.netlify.app/) |
| 115 | +- [Perfume.js documentation](https://zizzamia.github.io/perfume/) |
| 116 | +- [Analytics library docs](https://github.com/DavidWells/analytics) |
| 117 | +- [Example video](https://www.youtube.com/watch?v=9DZAVpAubtQ) |
0 commit comments