Performance Optimization Workflow

Full performance review and optimization workflow across database, frontend, and infrastructure layers

The Performance Optimization workflow provides a structured approach to analyzing and improving application performance across all layers of your stack, from database queries to frontend rendering.

Overview#

PropertyValue
Phases4
TierFree
Typical Duration6-10 days
Best ForSlow applications, scaling preparation, user experience improvement

Outcomes#

A successful performance optimization results in:

  • Performance regressions identified and resolved
  • Hotspots addressed across stack layers
  • Baseline metrics captured
  • Improvement report documented

Phases#

Phase 1: Analysis (1-2 days)#

Agents: performance-expert

Establish performance baselines and identify bottlenecks across the application.

Tasks:

  • Measure current performance metrics (Core Web Vitals)
  • Profile server response times
  • Identify slow endpoints and queries
  • Analyze bundle sizes and load times
  • Review caching strategies
  • Document baseline metrics

Key Metrics:

┌─────────────────────────────────────────────────────────┐ │ Core Web Vitals │ ├──────────────────┬──────────────────┬───────────────────┤ │ LCP │ FID │ CLS │ │ Largest │ First Input │ Cumulative │ │ Contentful Paint │ Delay │ Layout Shift │ │ < 2.5s │ < 100ms │ < 0.1 │ └──────────────────┴──────────────────┴───────────────────┘

Analysis Commands:

1# Lighthouse audit 2npx lighthouse https://your-app.com --output json 3 4# Bundle analysis (Next.js) 5ANALYZE=true npm run build 6 7# Server profiling 8bootspring agent invoke performance-expert "Profile API endpoints"

Phase 2: Database Optimization (2-3 days)#

Agents: database-expert, performance-expert

Optimize database queries, indexes, and data access patterns.

Tasks:

  • Identify slow queries using EXPLAIN ANALYZE
  • Add missing indexes for common query patterns
  • Optimize N+1 query problems
  • Implement query result caching
  • Review connection pooling configuration
  • Consider read replicas for heavy read workloads

Common Optimizations:

1-- Identify slow queries (PostgreSQL) 2SELECT query, calls, mean_time, total_time 3FROM pg_stat_statements 4ORDER BY mean_time DESC 5LIMIT 10; 6 7-- Add composite index for common queries 8CREATE INDEX idx_orders_user_status 9ON orders(user_id, status); 10 11-- Analyze query execution 12EXPLAIN ANALYZE 13SELECT * FROM orders 14WHERE user_id = 'xyz' AND status = 'pending';

Prisma Optimizations:

1// Before: N+1 problem 2const users = await prisma.user.findMany(); 3for (const user of users) { 4 const orders = await prisma.order.findMany({ 5 where: { userId: user.id } 6 }); 7} 8 9// After: Eager loading 10const users = await prisma.user.findMany({ 11 include: { 12 orders: true 13 } 14});

Phase 3: Frontend Optimization (2-3 days)#

Agents: frontend-expert, performance-expert

Optimize client-side performance, rendering, and asset delivery.

Tasks:

  • Reduce JavaScript bundle size
  • Implement code splitting and lazy loading
  • Optimize images and media assets
  • Improve First Contentful Paint (FCP)
  • Reduce Cumulative Layout Shift (CLS)
  • Implement proper caching headers

Bundle Optimization:

1// Dynamic imports for code splitting 2const HeavyComponent = dynamic( 3 () => import('@/components/HeavyComponent'), 4 { 5 loading: () => <Skeleton />, 6 ssr: false // Client-only if needed 7 } 8); 9 10// Route-based code splitting (automatic in Next.js App Router) 11// Each route segment loads independently

Image Optimization:

1import Image from 'next/image'; 2 3// Optimized image loading 4<Image 5 src="/hero.jpg" 6 alt="Hero image" 7 width={1200} 8 height={600} 9 priority // For above-the-fold images 10 placeholder="blur" 11 blurDataURL={blurDataUrl} 12/>

Font Optimization:

1// app/layout.tsx 2import { Inter } from 'next/font/google'; 3 4const inter = Inter({ 5 subsets: ['latin'], 6 display: 'swap', // Prevent layout shift 7 preload: true, 8});

Phase 4: Infrastructure Optimization (1-2 days)#

Agents: devops-expert

Optimize server configuration, caching, and content delivery.

Tasks:

  • Configure CDN for static assets
  • Implement edge caching strategies
  • Optimize serverless function cold starts
  • Review server-side caching (Redis)
  • Configure proper cache headers
  • Set up performance monitoring

Caching Strategy:

┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ Browser │───▶│ CDN │───▶│ Origin │ │ Cache │ │ Cache │ │ Server │ └─────────────┘ └─────────────┘ └─────────────┘ │ │ │ ▼ ▼ ▼ Static assets Edge cached Dynamic API max-age=1y stale-while- responses revalidate

Cache Headers Example:

1// next.config.js 2module.exports = { 3 async headers() { 4 return [ 5 { 6 source: '/static/:path*', 7 headers: [ 8 { 9 key: 'Cache-Control', 10 value: 'public, max-age=31536000, immutable', 11 }, 12 ], 13 }, 14 { 15 source: '/api/:path*', 16 headers: [ 17 { 18 key: 'Cache-Control', 19 value: 'public, s-maxage=60, stale-while-revalidate=300', 20 }, 21 ], 22 }, 23 ]; 24 }, 25};

Starting the Workflow#

1# Start the workflow 2bootspring workflow start performance-optimization 3 4# Check current status 5bootspring workflow status 6 7# Advance to next phase 8bootspring workflow next 9 10# Mark a checkpoint complete 11bootspring workflow checkpoint "Baseline captured"

Completion Signals#

Track progress with these checkpoints:

  1. Baseline captured - Initial metrics documented
  2. Improvement report documented - Final metrics and improvements recorded

Performance Budget#

Set targets before optimization:

MetricTargetCritical
LCP< 2.5s< 4.0s
FID< 100ms< 300ms
CLS< 0.1< 0.25
TTI< 3.5s< 7.0s
Bundle Size< 200KB< 500KB
API P95< 200ms< 500ms

Monitoring Setup#

1// lib/monitoring.ts 2import * as Sentry from '@sentry/nextjs'; 3 4// Track Core Web Vitals 5export function reportWebVitals(metric: { 6 id: string; 7 name: string; 8 value: number; 9}) { 10 Sentry.captureMessage('Web Vital', { 11 extra: { 12 metric: metric.name, 13 value: metric.value, 14 id: metric.id, 15 }, 16 }); 17 18 // Send to analytics 19 if (window.gtag) { 20 window.gtag('event', metric.name, { 21 value: Math.round(metric.value), 22 event_label: metric.id, 23 non_interaction: true, 24 }); 25 } 26}

Tips for Success#

  1. Measure first - Always establish baselines before optimizing
  2. Prioritize by impact - Fix the biggest bottlenecks first
  3. Test in production conditions - Dev performance differs from prod
  4. Monitor continuously - Performance can regress over time
  5. Set budgets - Define acceptable limits for your metrics