4.8 KiB
4.8 KiB
Performance Optimization Task
Purpose
Systematic approach to identifying and resolving performance issues in JavaScript/TypeScript full-stack applications.
When to Use
- Performance targets not being met
- User complaints about slow loading
- High server costs due to inefficiency
- Preparing for increased scale
- Regular performance audits
Performance Optimization Process
1. Measure Current Performance
Frontend Metrics:
# Lighthouse CI
npm install -g @lhci/cli
lhci autorun
Backend Metrics:
- API response times (p50, p95, p99)
- Database query times
- Memory usage
- CPU usage
Tools:
- Lighthouse for frontend
- Chrome DevTools Performance tab
- React DevTools Profiler
- APM tools (Datadog, New Relic)
- Database query analyzers (EXPLAIN ANALYZE)
2. Identify Bottlenecks
Common Frontend Issues:
- Large bundle size
- Slow images
- Too many re-renders
- Blocking JavaScript
- Large third-party scripts
Common Backend Issues:
- Slow database queries (N+1 problems)
- Missing indexes
- No caching
- Synchronous operations
- Memory leaks
3. Frontend Optimization
Bundle Optimization
# Analyze bundle
npm run build
npx webpack-bundle-analyzer
Actions:
- Code split large components
- Lazy load routes
- Tree shake unused code
- Use dynamic imports
- Remove unused dependencies
Image Optimization
- Use next/image for automatic optimization
- Serve WebP format with fallbacks
- Lazy load images below fold
- Use appropriate sizes (responsive images)
- Compress images (TinyPNG, ImageOptim)
React Performance
// Memoize expensive components
const ExpensiveComponent = React.memo(({ data }) => {
// ...
});
// Memoize callbacks
const handleClick = useCallback(() => {
// ...
}, [deps]);
// Memoize expensive calculations
const sortedData = useMemo(() => {
return data.sort((a, b) => a.value - b.value);
}, [data]);
// Virtual scrolling for long lists
import { useVirtualizer } from '@tanstack/react-virtual';
Caching Strategy
// React Query caching
const { data } = useQuery({
queryKey: ['todos'],
queryFn: fetchTodos,
staleTime: 5 * 60 * 1000, // 5 minutes
cacheTime: 10 * 60 * 1000, // 10 minutes
});
4. Backend Optimization
Database Optimization
// Add indexes
await prisma.$executeRaw`
CREATE INDEX idx_users_email ON users(email);
`;
// Optimize queries
const users = await prisma.user.findMany({
select: {
id: true,
name: true,
email: true,
// Only select needed fields
},
where: {
isActive: true,
},
take: 20, // Limit results
});
// Prevent N+1
const postsWithAuthors = await prisma.post.findMany({
include: {
author: true, // Eager load
},
});
Caching Layer
import Redis from 'ioredis';
const redis = new Redis();
async function getCachedData(key: string, fetchFn: () => Promise<any>) {
// Try cache first
const cached = await redis.get(key);
if (cached) return JSON.parse(cached);
// Fetch and cache
const data = await fetchFn();
await redis.setex(key, 300, JSON.stringify(data)); // 5 min TTL
return data;
}
Background Jobs
import Queue from 'bull';
const emailQueue = new Queue('email', {
redis: { host: 'localhost', port: 6379 },
});
// Don't block API responses
app.post('/send-email', async (req, res) => {
await emailQueue.add({ to, subject, body });
res.json({ message: 'Email queued' });
});
5. Network Optimization
Enable Compression:
import compression from 'compression';
app.use(compression());
CDN for Static Assets:
- Host images, CSS, JS on CDN
- Use CloudFlare, AWS CloudFront, or Vercel Edge
HTTP/2:
- Enable HTTP/2 on server
- Reduces latency for multiple requests
6. Monitoring
Set Up Continuous Monitoring:
- Lighthouse CI in GitHub Actions
- Error rate alerts
- Response time alerts
- CPU/Memory usage alerts
Performance Budget:
{
"budgets": [{
"path": "/*",
"timings": [{
"metric": "interactive",
"budget": 3000
}],
"resourceSizes": [{
"resourceType": "script",
"budget": 200
}]
}]
}
Performance Targets
Frontend
- Lighthouse score: >90
- LCP (Largest Contentful Paint): < 2.5s
- FID (First Input Delay): < 100ms
- CLS (Cumulative Layout Shift): < 0.1
- Time to Interactive: < 3.5s
Backend
- API response time: < 200ms (p95)
- Database query time: < 100ms
- Error rate: < 0.1%
- Uptime: 99.9%
Validation
Use checklists/performance-checklist.md to validate all optimizations
Common Quick Wins
- Add database indexes
- Enable gzip compression
- Use CDN for static assets
- Add Redis caching
- Code split frontend
- Optimize images
- Lazy load components
- Remove unused dependencies