Skip to content

Implement Web Vitals tracking in Google Analytics #41

@michaeldistel

Description

@michaeldistel

Problem

No Core Web Vitals tracking:

  • Don't know real user performance
  • Can't measure LCP, FID, CLS
  • No data for performance regressions
  • Missing Google ranking signals

Solution

Use web-vitals library to track Core Web Vitals:

pnpm add web-vitals

Implementation

// src/lib/analytics/web-vitals.ts
import { onCLS, onFID, onLCP, onFCP, onTTFB } from 'web-vitals';

function sendToGoogleAnalytics({ name, delta, id, value }: any) {
  if (typeof gtag !== 'undefined') {
    gtag('event', name, {
      event_category: 'Web Vitals',
      event_label: id,
      value: Math.round(name === 'CLS' ? delta * 1000 : delta),
      non_interaction: true,
    });
  }
}

export function initWebVitals() {
  onCLS(sendToGoogleAnalytics);
  onFID(sendToGoogleAnalytics);
  onLCP(sendToGoogleAnalytics);
  onFCP(sendToGoogleAnalytics);
  onTTFB(sendToGoogleAnalytics);
}

Root Layout Integration

<!-- src/routes/+layout.svelte -->
<script>
  import { browser } from '$app/environment';
  import { initWebVitals } from '$lib/analytics/web-vitals';
  
  $: if (browser && import.meta.env.PROD) {
    initWebVitals();
  }
</script>

Metrics Tracked

Core Web Vitals

  1. LCP (Largest Contentful Paint)

    • Target: <2.5s
    • Measures: Loading performance
  2. FID (First Input Delay)

    • Target: <100ms
    • Measures: Interactivity
  3. CLS (Cumulative Layout Shift)

    • Target: <0.1
    • Measures: Visual stability

Additional Metrics

  1. FCP (First Contentful Paint)

    • Target: <1.8s
    • Measures: Perceived loading
  2. TTFB (Time to First Byte)

    • Target: <600ms
    • Measures: Server response

Google Analytics Setup

In GA4, create custom reports:

  1. Navigate to Explore
  2. Create Web Vitals report template
  3. View by page, device, connection type

Alert Thresholds

Set up alerts for:

  • LCP >2.5s on >25% of pageviews
  • FID >100ms on >25% of pageviews
  • CLS >0.1 on >25% of pageviews

Sentry Integration (Optional)

Send Web Vitals to Sentry for better analysis:

import * as Sentry from '@sentry/sveltekit';

function sendToSentry(metric: any) {
  Sentry.addBreadcrumb({
    category: 'web-vitals',
    message: `${metric.name}: ${metric.value}`,
    level: 'info',
  });
}

onLCP(metric => {
  sendToGoogleAnalytics(metric);
  sendToSentry(metric);
});

Dashboard

Create GA4 custom dashboard showing:

  • Web Vitals trends over time
  • Breakdown by page
  • Device comparison (mobile vs desktop)
  • Geographic performance

Success Criteria

  • Web Vitals tracked in GA4
  • Custom GA4 report created
  • Metrics visible per page
  • Alerts configured for poor scores
  • Monthly performance review process

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions