Falytom logoFALYTOM
Games
ToolsUI ComponentsServicesProductsAbout
menu
  1. Home
  2. /Web Development
  3. /Nextjs
  4. /Performance Analytics
Your Progress0%
0 of 70 completed

NextJS Topics

Getting Started

  • What is Next.js?
  • Next.js vs React - Key Differences
  • Creating Your First Next.js 15 Project
  • Next.js Project Structure Explained
  • App Router vs Pages Router

Routing Fundamentals

  • File-Based Routing Basics
  • Creating Pages with page.tsx
  • Dynamic Routes and Route Parameters
  • Catch-All and Optional Catch-All Routes
  • Route Groups for Organization
  • Parallel Routes
  • Intercepting Routes

Layouts and Pages

  • Understanding Layouts
  • Root Layout and Global Configuration
  • Nested Layouts
  • Templates vs Layouts
  • Loading States with loading.tsx
  • Error Handling with error.tsx

Server and Client Components

  • Understanding Server Components
  • Client Components with 'use client'
  • When to Use Server vs Client Components
  • Component Composition Patterns
  • Passing Props Between Server and Client
  • Server Component Patterns and Best Practices

Data Fetching

  • Fetching Data in Server Components
  • Parallel and Sequential Data Fetching
  • Data Fetching Patterns and Strategies
  • Caching and Revalidation
  • Revalidate and Cache Tags
  • Handling Loading and Error States in Data Fetching

Navigation and Links

  • Link Component Basics
  • useRouter Hook for Programmatic Navigation
  • usePathname and useSearchParams Hooks
  • Active Links and Navigation States
  • Redirects and Navigation Guards

Styling in Next.js

  • CSS Modules in Next.js
  • Tailwind CSS Setup and Configuration
  • Global Styles and CSS Variables
  • Next.js Font Optimization

Images and Media

  • Next.js Image Component Basics
  • Image Optimization and Best Practices
  • Working with Static Assets

Forms and Data Mutations

  • Understanding Server Actions
  • Form Handling with Server Actions
  • Form Validation and Error Handling
  • useFormStatus and useFormState Hooks
  • Revalidating Data After Mutations
  • Optimistic Updates

Metadata and SEO

  • Static Metadata Configuration
  • Dynamic Metadata Generation
  • Open Graph and Social Media Cards
  • Sitemap and Robots.txt

API Routes and Route Handlers

  • Route Handlers Introduction
  • GET and POST Request Handlers
  • Dynamic API Routes
  • Request and Response Objects
  • API Error Handling and Status Codes

Middleware and Advanced Features

  • Introduction to Middleware
  • Authentication with Middleware
  • Environment Variables and Configuration
  • Streaming and Suspense
  • Not Found and Global Error Pages

Deployment and Optimization

  • Understanding Static and Dynamic Rendering
  • generateStaticParams for Static Generation
  • Build and Production Optimization
  • Deploying to Vercel
  • Alternative Deployment Options
  • Performance Monitoring and Analytics

Real-World Projects

  • Project 1: E-commerce Product Catalog
  • Project 2: Dashboard with Authentication

Performance Monitoring and Analytics

Tracking and optimizing real user performance

You can't optimize what you don't measure! Track Core Web Vitals to measure real user experience, integrate analytics to understand user behavior, monitor errors to catch issues early, and use performance data to guide optimization. Master monitoring and build data-driven, high-performance applications that delight users!

Core Web Vitals

The Three Core Web Vitals

1. LCP (Largest Contentful Paint)

Measures: Loading performance

What it tracks: Time until largest content element is visible

Good: < 2.5 seconds

Needs improvement: 2.5 - 4 seconds

Poor: > 4 seconds

2. INP (Interaction to Next Paint)

Measures: Interactivity and responsiveness

What it tracks: Time from user interaction to visual response

Good: < 200ms

Needs improvement: 200 - 500ms

Poor: > 500ms

Note: INP replaced FID in March 2024

3. CLS (Cumulative Layout Shift)

Measures: Visual stability

What it tracks: Unexpected layout shifts during page load

Good: < 0.1

Needs improvement: 0.1 - 0.25

Poor: > 0.25

Why Core Web Vitals Matter

  • SEO Impact: Google uses Web Vitals as ranking signals
  • User Experience: Direct correlation with user satisfaction
  • Conversion Rates: Better vitals = higher conversions
  • Competitive Advantage: Stand out with better performance

Tracking Web Vitals in Next.js

useReportWebVitals Hook

app/components/WebVitals.tsx
'use client';

import { useReportWebVitals } from 'next/web-vitals';

export function WebVitals() {
  useReportWebVitals((metric) => {
    // Log to console (development)
    if (process.env.NODE_ENV === 'development') {
      console.log(metric);
    }
    
    // Send to analytics (production)
    if (process.env.NODE_ENV === 'production') {
      const body = JSON.stringify({
        name: metric.name,
        value: metric.value,
        rating: metric.rating,
        delta: metric.delta,
        id: metric.id,
      });
      
      // Use sendBeacon for reliability
      if (navigator.sendBeacon) {
        navigator.sendBeacon('/api/analytics', body);
      } else {
        fetch('/api/analytics', {
          body,
          method: 'POST',
          keepalive: true,
        });
      }
    }
  });
  
  return null;
}

// Add to layout:
// <WebVitals />

// ✅ Tracks all Core Web Vitals
// ✅ Captures real user metrics
// ✅ Sends to analytics endpoint

Web Vitals API Route

app/api/analytics/route.ts
import { NextResponse } from 'next/server';

export async function POST(request: Request) {
  try {
    const metric = await request.json();
    
    // Log metric
    console.log('Web Vital:', metric);
    
    // Send to analytics service (Google Analytics, custom service, etc.)
    await sendToAnalytics(metric);
    
    return NextResponse.json({ success: true });
  } catch (error) {
    console.error('Analytics error:', error);
    return NextResponse.json(
      { success: false },
      { status: 500 }
    );
  }
}

async function sendToAnalytics(metric: any) {
  // Example: Send to Google Analytics
  if (typeof window !== 'undefined' && window.gtag) {
    window.gtag('event', metric.name, {
      value: Math.round(metric.value),
      metric_id: metric.id,
      metric_rating: metric.rating,
      metric_delta: metric.delta,
    });
  }
  
  // Or send to custom analytics service
  // await fetch('https://analytics.example.com/metrics', {
  //   method: 'POST',
  //   body: JSON.stringify(metric),
  // });
}

// ✅ Receives Web Vitals data
// ✅ Processes metrics
// ✅ Forwards to analytics service

Vercel Analytics Integration

app/layout.tsx
import { Analytics } from '@vercel/analytics/react';
import { SpeedInsights } from '@vercel/speed-insights/next';

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        {children}
        
        {/* Vercel Analytics */}
        <Analytics />
        
        {/* Vercel Speed Insights */}
        <SpeedInsights />
      </body>
    </html>
  );
}

// Install packages:
// npm install @vercel/analytics @vercel/speed-insights

// ✅ Automatic Web Vitals tracking
// ✅ Real user monitoring
// ✅ Performance insights dashboard
// ✅ No configuration needed

Google Analytics Integration

Google Analytics 4 Setup

app/components/Analytics.tsx
'use client';

import Script from 'next/script';

export function GoogleAnalytics({ GA_MEASUREMENT_ID }: { GA_MEASUREMENT_ID: string }) {
  return (
    <>
      <Script
        src={`https://www.googletagmanager.com/gtag/js?id=${GA_MEASUREMENT_ID}`}
        strategy="afterInteractive"
      />
      <Script id="google-analytics" strategy="afterInteractive">
        {`
          window.dataLayer = window.dataLayer || [];
          function gtag(){dataLayer.push(arguments);}
          gtag('js', new Date());

          gtag('config', '${GA_MEASUREMENT_ID}', {
            page_path: window.location.pathname,
          });
        `}
      </Script>
    </>
  );
}

// Usage in layout:
// <GoogleAnalytics GA_MEASUREMENT_ID={process.env.NEXT_PUBLIC_GA_ID!} />

// ✅ Next.js Script component for optimization
// ✅ afterInteractive strategy (doesn't block page)
// ✅ Page view tracking

Track Custom Events

lib/analytics.ts
// Declare gtag function
declare global {
  interface Window {
    gtag: (
      command: string,
      ...args: any[]
    ) => void;
  }
}

// Track page views
export const trackPageView = (url: string) => {
  if (typeof window.gtag !== 'undefined') {
    window.gtag('config', process.env.NEXT_PUBLIC_GA_ID!, {
      page_path: url,
    });
  }
};

// Track custom events
export const trackEvent = (
  action: string,
  category: string,
  label?: string,
  value?: number
) => {
  if (typeof window.gtag !== 'undefined') {
    window.gtag('event', action, {
      event_category: category,
      event_label: label,
      value: value,
    });
  }
};

// Track conversions
export const trackConversion = (conversionId: string) => {
  if (typeof window.gtag !== 'undefined') {
    window.gtag('event', 'conversion', {
      send_to: conversionId,
    });
  }
};

// Usage:
// trackEvent('click', 'Button', 'Sign Up');
// trackConversion('AW-CONVERSION-ID');

// ✅ Type-safe event tracking
// ✅ Reusable utilities
// ✅ Custom event support

Track Navigation in App Router

app/components/Analytics.tsx
'use client';

import { useEffect } from 'react';
import { usePathname, useSearchParams } from 'next/navigation';
import { trackPageView } from '@/lib/analytics';

export function PageViewTracker() {
  const pathname = usePathname();
  const searchParams = useSearchParams();
  
  useEffect(() => {
    if (pathname) {
      const url = pathname + (searchParams?.toString() ? `?${searchParams}` : '');
      trackPageView(url);
    }
  }, [pathname, searchParams]);
  
  return null;
}

// Add to layout:
// <PageViewTracker />

// ✅ Tracks all page navigations
// ✅ Works with App Router
// ✅ Includes search params

Error Monitoring

Sentry Integration

BASH
# Install Sentry
npm install @sentry/nextjs

# Initialize Sentry
npx @sentry/wizard@latest -i nextjs

# This creates:
# - sentry.client.config.js
# - sentry.server.config.js
# - sentry.edge.config.js
# - next.config.js updates

# ✅ Automatic error tracking
# ✅ Performance monitoring
# ✅ Release tracking

Sentry Configuration

sentry.client.config.ts
import * as Sentry from '@sentry/nextjs';

Sentry.init({
  dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
  
  // Performance monitoring
  tracesSampleRate: 1.0,
  
  // Session replay
  replaysOnErrorSampleRate: 1.0,
  replaysSessionSampleRate: 0.1,
  
  // Environment
  environment: process.env.NODE_ENV,
  
  // Integrations
  integrations: [
    new Sentry.BrowserTracing(),
    new Sentry.Replay({
      maskAllText: true,
      blockAllMedia: true,
    }),
  ],
});

// ✅ Client-side error tracking
// ✅ Performance traces
// ✅ Session replays

Custom Error Handling

app/error.tsx
'use client';

import { useEffect } from 'react';
import * as Sentry from '@sentry/nextjs';

export default function Error({
  error,
  reset,
}: {
  error: Error & { digest?: string };
  reset: () => void;
}) {
  useEffect(() => {
    // Log error to Sentry
    Sentry.captureException(error, {
      tags: {
        error_boundary: 'app',
      },
      contexts: {
        error: {
          digest: error.digest,
        },
      },
    });
  }, [error]);

  return (
    <div>
      <h2>Something went wrong!</h2>
      <button onClick={reset}>Try again</button>
    </div>
  );
}

// ✅ Captures errors in error boundary
// ✅ Sends to Sentry with context
// ✅ User can retry

Manual Error Logging

lib/monitoring.ts
import * as Sentry from '@sentry/nextjs';

// Log errors
export function logError(error: Error, context?: Record<string, any>) {
  console.error('Error:', error);
  
  if (process.env.NODE_ENV === 'production') {
    Sentry.captureException(error, {
      extra: context,
    });
  }
}

// Log messages
export function logMessage(
  message: string,
  level: 'info' | 'warning' | 'error' = 'info'
) {
  console.log(`[${level.toUpperCase()}]`, message);
  
  if (process.env.NODE_ENV === 'production') {
    Sentry.captureMessage(message, level);
  }
}

// Set user context
export function setUser(user: { id: string; email: string }) {
  if (process.env.NODE_ENV === 'production') {
    Sentry.setUser(user);
  }
}

// Usage:
// logError(new Error('Something failed'), { userId: '123' });
// logMessage('User signed up', 'info');
// setUser({ id: '123', email: 'user@example.com' });

// ✅ Centralized error logging
// ✅ User context tracking
// ✅ Production-only in Sentry

Analytics and Monitoring Structure

Files for performance tracking

appImportant
lib

Select a file or folder to see details

Custom Performance Metrics

Performance API

lib/performance.ts
// Measure custom timings
export function measureTiming(name: string, startMark: string, endMark: string) {
  try {
    performance.measure(name, startMark, endMark);
    const measure = performance.getEntriesByName(name)[0];
    
    console.log(`${name}: ${measure.duration.toFixed(2)}ms`);
    
    // Send to analytics
    sendMetric(name, measure.duration);
    
    return measure.duration;
  } catch (error) {
    console.error('Performance measurement error:', error);
    return 0;
  }
}

// Mark start of operation
export function markStart(name: string) {
  performance.mark(`${name}-start`);
}

// Mark end of operation
export function markEnd(name: string) {
  performance.mark(`${name}-end`);
  return measureTiming(name, `${name}-start`, `${name}-end`);
}

// Usage:
// markStart('data-fetch');
// await fetchData();
// markEnd('data-fetch'); // Logs: "data-fetch: 234.56ms"

// ✅ Custom timing measurements
// ✅ Track specific operations
// ✅ Send to analytics

Component Performance

components/ExpensiveComponent.tsx
'use client';

import { useEffect } from 'react';
import { markStart, markEnd } from '@/lib/performance';

export function ExpensiveComponent() {
  useEffect(() => {
    markStart('expensive-component-render');
    
    // Component mounted
    return () => {
      // Component unmounting
      markEnd('expensive-component-render');
    };
  }, []);
  
  return <div>Expensive Component</div>;
}

// ✅ Track component render time
// ✅ Identify slow components
// ✅ Optimize based on data

API Performance Tracking

lib/api.ts
async function fetchWithMetrics<T>(
  url: string,
  options?: RequestInit
): Promise<T> {
  const startTime = performance.now();
  
  try {
    const response = await fetch(url, options);
    const data = await response.json();
    
    const duration = performance.now() - startTime;
    
    // Log API call metrics
    console.log(`API call to ${url}: ${duration.toFixed(2)}ms`);
    
    // Send to analytics
    sendMetric('api-call', duration, {
      url,
      status: response.status,
    });
    
    return data;
  } catch (error) {
    const duration = performance.now() - startTime;
    
    // Log failed API call
    console.error(`API call failed to ${url}: ${duration.toFixed(2)}ms`, error);
    
    sendMetric('api-call-error', duration, {
      url,
      error: (error as Error).message,
    });
    
    throw error;
  }
}

// ✅ Track all API calls
// ✅ Measure response times
// ✅ Log errors with timing

Lighthouse CI

Lighthouse CI Configuration

lighthouserc.js
module.exports = {
  ci: {
    collect: {
      // Run Lighthouse on these URLs
      url: [
        'http://localhost:3000/',
        'http://localhost:3000/about',
        'http://localhost:3000/blog',
      ],
      // Number of runs per URL
      numberOfRuns: 3,
    },
    assert: {
      // Assertions for performance budgets
      assertions: {
        'categories:performance': ['error', { minScore: 0.9 }],
        'categories:accessibility': ['error', { minScore: 0.9 }],
        'categories:best-practices': ['error', { minScore: 0.9 }],
        'categories:seo': ['error', { minScore: 0.9 }],
      },
    },
    upload: {
      // Upload to Lighthouse CI server (optional)
      target: 'temporary-public-storage',
    },
  },
};

// ✅ Automated performance testing
// ✅ Performance budgets
// ✅ CI/CD integration

GitHub Actions with Lighthouse CI

.github/workflows/lighthouse.yml
name: Lighthouse CI

on:
  pull_request:
    branches: [main]

jobs:
  lighthouse:
    runs-on: ubuntu-latest
    
    steps:
      - uses: actions/checkout@v3
      
      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: 18
      
      - name: Install dependencies
        run: npm ci
      
      - name: Build application
        run: npm run build
      
      - name: Start server
        run: npm start &
        
      - name: Wait for server
        run: npx wait-on http://localhost:3000
      
      - name: Run Lighthouse CI
        run: |
          npm install -g @lhci/cli
          lhci autorun
        env:
          LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_GITHUB_APP_TOKEN }}

# ✅ Automatic performance checks on PRs
# ✅ Prevents performance regressions
# ✅ Comments on PRs with results

Optimization Strategies Based on Metrics

Improving LCP (Loading)

Strategies:

  • Optimize images (use Next.js Image component)
  • Preload critical assets
  • Use CDN for static assets
  • Implement proper caching
  • Minimize server response time
  • Remove render-blocking resources

Improving INP (Interactivity)

Strategies:

  • Code split large JavaScript bundles
  • Use dynamic imports for heavy components
  • Defer non-critical JavaScript
  • Optimize event handlers
  • Use Web Workers for heavy computations
  • Reduce main thread work

Improving CLS (Visual Stability)

Strategies:

  • Set width and height on images and videos
  • Reserve space for dynamic content
  • Avoid inserting content above existing content
  • Use CSS transform animations instead of layout properties
  • Preload fonts to avoid FOUT
  • Set explicit dimensions on ad slots

Production Monitoring Checklist

✅ Essential Monitoring

  • Web Vitals: Track LCP, INP, CLS
  • Analytics: Google Analytics or alternative
  • Error Tracking: Sentry or similar service
  • Performance: Custom metrics for critical operations
  • Uptime: Monitor server availability
  • Alerts: Set up notifications for critical issues
  • Logs: Centralized logging for debugging
  • Budgets: Performance budgets in CI/CD

Key Takeaways

  • Core Web Vitals - LCP, INP, CLS measure user experience
  • useReportWebVitals - track Web Vitals in Next.js
  • Analytics integration - Google Analytics, Vercel Analytics
  • Error monitoring - Sentry for production error tracking
  • Custom metrics - Performance API for specific operations
  • Lighthouse CI - automated performance testing
  • Real user monitoring - measure actual user experiences
  • Data-driven optimization - optimize based on metrics

🎉 Congratulations!

You've completed the complete Next.js 15 tutorial series! You've mastered:

What You've Learned:

  • ✅ Routing Fundamentals - App Router, dynamic routes, layouts
  • ✅ Server & Client Components - composition patterns, when to use each
  • ✅ Data Fetching - SSG, SSR, ISR, caching strategies
  • ✅ Navigation & Links - prefetching, programmatic navigation
  • ✅ Styling - CSS Modules, Tailwind, CSS-in-JS
  • ✅ Images & Media - optimization, responsive images
  • ✅ Forms & Mutations - Server Actions, validation, optimistic updates
  • ✅ Metadata & SEO - dynamic metadata, Open Graph, sitemaps
  • ✅ API Routes - REST APIs, error handling, authentication
  • ✅ Middleware - request interception, authentication
  • ✅ Environment Variables - configuration, security
  • ✅ Streaming & Suspense - progressive rendering, loading states
  • ✅ Error Handling - not-found, error boundaries
  • ✅ Rendering Strategies - static, dynamic, ISR
  • ✅ Static Generation - generateStaticParams
  • ✅ Build Optimization - bundle analysis, code splitting
  • ✅ Deployment - Vercel, AWS, Docker, self-hosting
  • ✅ Monitoring & Analytics - Web Vitals, error tracking

You're now ready to build production-ready, high-performance, and scalable Next.js applications! 🚀

🎓 Next Steps

Continue your Next.js journey by building real projects! Apply what you've learned: build a blog with MDX, an e-commerce site, a SaaS application, or contribute to open-source Next.js projects. The best way to solidify your knowledge is to build!

Final Quiz - Test Your Understanding

Question 1 of 4

What are Core Web Vitals?

Master Next.js performance monitoring! Learn Core Web Vitals, analytics, and optimization strategies.

Previous
Alternative Deployment Options
Next
Project 1: E-commerce Product Catalog

Continue Your Web Development Journey

You've completed the Next.js tutorial series! Join 2,000+ developers and stay updated with new tutorials, advanced topics, and best practices - 100% FREE.

You might also like

UI Components

Ready-made components for your projects

Developer Tools

Boost productivity with handy generators

HTML Game

Learn HTML concepts through interactive gameplay

Join Our Web Development Training Program

Master frontend & backend development with hands-on projects.

NextJS Tutorials

0 of 70 completed

Your Progress0%

Topics

Getting Started

  • What is Next.js?
  • Next.js vs React - Key Differences
  • Creating Your First Next.js 15 Project
  • Next.js Project Structure Explained
  • App Router vs Pages Router

Routing Fundamentals

  • File-Based Routing Basics
  • Creating Pages with page.tsx
  • Dynamic Routes and Route Parameters
  • Catch-All and Optional Catch-All Routes
  • Route Groups for Organization
  • Parallel Routes
  • Intercepting Routes

Layouts and Pages

  • Understanding Layouts
  • Root Layout and Global Configuration
  • Nested Layouts
  • Templates vs Layouts
  • Loading States with loading.tsx
  • Error Handling with error.tsx

Server and Client Components

  • Understanding Server Components
  • Client Components with 'use client'
  • When to Use Server vs Client Components
  • Component Composition Patterns
  • Passing Props Between Server and Client
  • Server Component Patterns and Best Practices

Data Fetching

  • Fetching Data in Server Components
  • Parallel and Sequential Data Fetching
  • Data Fetching Patterns and Strategies
  • Caching and Revalidation
  • Revalidate and Cache Tags
  • Handling Loading and Error States in Data Fetching

Navigation and Links

  • Link Component Basics
  • useRouter Hook for Programmatic Navigation
  • usePathname and useSearchParams Hooks
  • Active Links and Navigation States
  • Redirects and Navigation Guards

Styling in Next.js

  • CSS Modules in Next.js
  • Tailwind CSS Setup and Configuration
  • Global Styles and CSS Variables
  • Next.js Font Optimization

Images and Media

  • Next.js Image Component Basics
  • Image Optimization and Best Practices
  • Working with Static Assets

Forms and Data Mutations

  • Understanding Server Actions
  • Form Handling with Server Actions
  • Form Validation and Error Handling
  • useFormStatus and useFormState Hooks
  • Revalidating Data After Mutations
  • Optimistic Updates

Metadata and SEO

  • Static Metadata Configuration
  • Dynamic Metadata Generation
  • Open Graph and Social Media Cards
  • Sitemap and Robots.txt

API Routes and Route Handlers

  • Route Handlers Introduction
  • GET and POST Request Handlers
  • Dynamic API Routes
  • Request and Response Objects
  • API Error Handling and Status Codes

Middleware and Advanced Features

  • Introduction to Middleware
  • Authentication with Middleware
  • Environment Variables and Configuration
  • Streaming and Suspense
  • Not Found and Global Error Pages

Deployment and Optimization

  • Understanding Static and Dynamic Rendering
  • generateStaticParams for Static Generation
  • Build and Production Optimization
  • Deploying to Vercel
  • Alternative Deployment Options
  • Performance Monitoring and Analytics

Real-World Projects

  • Project 1: E-commerce Product Catalog
  • Project 2: Dashboard with Authentication
Falytom logoFALYTOM

Learn technologies like HTML, CSS, JavaScript, React, NodeJS and more through interactive games, tutorials, components and free tools. Transform your businesses with AI chatbots, SEO-optimized websites, and professional development services.

© 2025 Tomilola Group
  • Facebook logo
  • Twitter logo
  • Instagram logo
  • LinkedIn logo
  • GitHub logo
  • YouTube logo