feat: add Core Web Vitals reporting to PostHog
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
35
frontend/src/lib/webVitals.ts
Normal file
35
frontend/src/lib/webVitals.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* Core Web Vitals reporting via PostHog.
|
||||
*
|
||||
* Tracks LCP, INP, CLS, FCP, and TTFB as PostHog events so we can
|
||||
* build dashboards and correlate performance with product usage.
|
||||
*
|
||||
* Each metric fires once per page load. PostHog captures 100% of
|
||||
* sessions (vs Sentry's 20% sample), giving better coverage.
|
||||
*/
|
||||
import { onLCP, onINP, onCLS, onFCP, onTTFB } from 'web-vitals'
|
||||
import type { Metric } from 'web-vitals'
|
||||
import posthog from 'posthog-js'
|
||||
|
||||
function sendToPostHog(metric: Metric) {
|
||||
// Only send if PostHog is loaded
|
||||
if (!(posthog as unknown as { __loaded?: boolean }).__loaded) return
|
||||
|
||||
posthog.capture('web_vitals', {
|
||||
metric_name: metric.name,
|
||||
metric_value: metric.value,
|
||||
metric_rating: metric.rating,
|
||||
metric_delta: metric.delta,
|
||||
metric_id: metric.id,
|
||||
page_path: window.location.pathname,
|
||||
})
|
||||
}
|
||||
|
||||
/** Register all Web Vitals observers. Call once after PostHog init. */
|
||||
export function initWebVitals() {
|
||||
onLCP(sendToPostHog)
|
||||
onINP(sendToPostHog)
|
||||
onCLS(sendToPostHog)
|
||||
onFCP(sendToPostHog)
|
||||
onTTFB(sendToPostHog)
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import { createRoot } from 'react-dom/client'
|
||||
import { reactErrorHandler } from '@sentry/react'
|
||||
import { HelmetProvider } from 'react-helmet-async'
|
||||
import { PostHogProvider } from '@posthog/react'
|
||||
import { initWebVitals } from './lib/webVitals'
|
||||
import { Toaster } from 'sonner'
|
||||
import './index.css'
|
||||
import App from './App'
|
||||
@@ -22,6 +23,9 @@ if (posthogKey) {
|
||||
})
|
||||
}
|
||||
|
||||
// Start Web Vitals reporting to PostHog
|
||||
initWebVitals()
|
||||
|
||||
createRoot(document.getElementById('root')!, {
|
||||
onUncaughtError: reactErrorHandler(),
|
||||
onCaughtError: reactErrorHandler(),
|
||||
|
||||
Reference in New Issue
Block a user