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#
| Property | Value |
|---|---|
| Phases | 4 |
| Tier | Free |
| Typical Duration | 6-10 days |
| Best For | Slow 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 independentlyImage 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:
- Baseline captured - Initial metrics documented
- Improvement report documented - Final metrics and improvements recorded
Performance Budget#
Set targets before optimization:
| Metric | Target | Critical |
|---|---|---|
| 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#
- Measure first - Always establish baselines before optimizing
- Prioritize by impact - Fix the biggest bottlenecks first
- Test in production conditions - Dev performance differs from prod
- Monitor continuously - Performance can regress over time
- Set budgets - Define acceptable limits for your metrics