[ PROMPT_NODE_26049 ]
Performance Optimizer
[ SKILL_DOCUMENTATION ]
# Performance Optimizer
Find and fix performance bottlenecks. Measure, optimize, verify. Make it fast.
## When to Use This Skill
- App is slow or laggy
- User complains about performance
- Page load times are high
- API responses are slow
- Database queries take too long
- User mentions "slow", "lag", "performance", or "optimize"
## The Optimization Process
### 1. Measure First
Never optimize without measuring:
```javascript
// Measure execution time
console.time('operation');
await slowOperation();
console.timeEnd('operation'); // operation: 2341ms
```
**What to measure:**
- Page load time
- API response time
- Database query time
- Function execution time
- Memory usage
- Network requests
### 2. Find the Bottleneck
Use profiling tools to find the slow parts:
**Browser:**
```
DevTools → Performance tab → Record → Stop
Look for long tasks (red bars)
```
**Node.js:**
```bash
node --prof app.js
node --prof-process isolate-*.log > profile.txt
```
**Database:**
```sql
EXPLAIN ANALYZE SELECT * FROM users WHERE email = '[email protected]';
```
### 3. Optimize
Fix the slowest thing first (biggest impact).
## Common Optimizations
### Database Queries
**Problem: N+1 Queries**
```javascript
// Bad: N+1 queries
const users = await db.users.find();
for (const user of users) {
user.posts = await db.posts.find({ userId: user.id }); // N queries
}
// Good: Single query with JOIN
const users = await db.users.find()
.populate('posts'); // 1 query
```
**Problem: Missing Index**
```sql
-- Check slow query
EXPLAIN SELECT * FROM users WHERE email = '[email protected]';
-- Shows: Seq Scan (bad)
-- Add index
CREATE INDEX idx_users_email ON users(email);
-- Check again
EXPLAIN SELECT * FROM users WHERE email = '[email protected]';
-- Shows: Index Scan (good)
```
**Problem: SELECT ***
```javascript
// Bad: Fetches all columns
const users = await db.query('SELECT * FROM users');
// Good: Only needed columns
const users = await db.query('SELECT id, name, email FROM users');
```
**Problem: No Pagination**
```javascript
// Bad: Returns all records
const users = await db.users.find();
// Good: Paginated
const users = await db.users.find()
.limit(20)
.skip((page - 1) * 20);
```
### API Performance
**Problem: No Caching**
```javascript
// Bad: Hits database every time
app.get('/api/stats', async (req, res) => {
const stats = await db.stats.calculate(); // Slow
res.json(stats);
});
// Good: Cache for 5 minutes
const cache = new Map();
app.get('/api/stats', async (req, res) => {
const cached = cache.get('stats');
if (cached && Date.now() - cached.time ({
id: u.id,
name: u.name,
email: u.email
}))); // 500KB response
```
### Frontend Performance
**Problem: Unnecessary Re-renders**
```javascript
// Bad: Re-renders on every parent update
function UserList({ users }) {
return users.map(user => );
}
// Good: Memoized
const UserCard = React.memo(({ user }) => {
return
```
### Algorithm Optimization
**Problem: Inefficient Algorithm**
```javascript
// Bad: O(n²) - nested loops
function findDuplicates(arr) {
const duplicates = [];
for (let i = 0; i < arr.length; i++) {
for (let j = i + 1; j sum + item.price * item.quantity, 0);
}
// Called 100 times in render
// Good: Memoized
const getTotal = useMemo(() => {
return items.reduce((sum, item) => sum + item.price * item.quantity, 0);
}, [items]);
```
### Memory Optimization
**Problem: Memory Leak**
```javascript
// Bad: Event listener not cleaned up
useEffect(() => {
window.addEventListener('scroll', handleScroll);
// Memory leak!
}, []);
// Good: Cleanup
useEffect(() => {
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, []);
```
**Problem: Large Data in Memory**
```javascript
// Bad: Loads entire file into memory
const data = fs.readFileSync('huge-file.txt'); // 1GB
// Good: Stream it
const stream = fs.createReadStream('huge-file.txt');
stream.on('data', chunk => process(chunk));
```
## Measuring Impact
Always measure before and after:
```javascript
// Before optimization
console.time('query');
const users = await db.users.find();
console.timeEnd('query');
// query: 2341ms
// After optimization (added index)
console.time('query');
const users = await db.users.find();
console.timeEnd('query');
// query: 23ms
// Improvement: 100x faster!
```
## Performance Budgets
Set targets:
```
Page Load: < 2 seconds
API Response: < 200ms
Database Query: < 50ms
Bundle Size: < 200KB
Time to Interactive: < 3 seconds
```
## Tools
**Browser:**
- Chrome DevTools Performance tab
- Lighthouse (audit)
- Network tab (waterfall)
**Node.js:**
- `node --prof` (profiling)
- `clinic` (diagnostics)
- `autocannon` (load testing)
**Database:**
- `EXPLAIN ANALYZE` (query plans)
- Slow query log
- Database profiler
**Monitoring:**
- New Relic
- Datadog
- Sentry Performance
## Quick Wins
Easy optimizations with big impact:
1. **Add database indexes** on frequently queried columns
2. **Enable gzip compression** on server
3. **Add caching** for expensive operations
4. **Lazy load** images and heavy components
5. **Use CDN** for static assets
6. **Minify and compress** JavaScript/CSS
7. **Remove unused dependencies**
8. **Use pagination** instead of loading all data
9. **Optimize images** (WebP, proper sizing)
10. **Enable HTTP/2** on server
## Optimization Checklist
- [ ] Measured current performance
- [ ] Identified bottleneck
- [ ] Applied optimization
- [ ] Measured improvement
- [ ] Verified functionality still works
- [ ] No new bugs introduced
- [ ] Documented the change
## When NOT to Optimize
- Premature optimization (optimize when it's actually slow)
- Micro-optimizations (save 1ms when page takes 5 seconds)
- Readable code is more important than tiny speed gains
- If it's already fast enough
## Key Principles
- Measure before optimizing
- Fix the biggest bottleneck first
- Measure after to prove improvement
- Don't sacrifice readability for tiny gains
- Profile in production-like environment
- Consider the 80/20 rule (20% of code causes 80% of slowness)
## Related Skills
- `@database-design` - Query optimization
- `@codebase-audit-pre-push` - Code review
- `@bug-hunter` - Debugging
{user.name}
;
});
```
**Problem: Large Bundle**
```javascript
// Bad: Imports entire library
import _ from 'lodash'; // 70KB
// Good: Import only what you need
import debounce from 'lodash/debounce'; // 2KB
```
**Problem: No Code Splitting**
```javascript
// Bad: Everything in one bundle
import HeavyComponent from './HeavyComponent';
// Good: Lazy load
const HeavyComponent = React.lazy(() => import('./HeavyComponent'));
```
**Problem: Unoptimized Images**
```html
```
### Algorithm Optimization
**Problem: Inefficient Algorithm**
```javascript
// Bad: O(n²) - nested loops
function findDuplicates(arr) {
const duplicates = [];
for (let i = 0; i < arr.length; i++) {
for (let j = i + 1; j sum + item.price * item.quantity, 0);
}
// Called 100 times in render
// Good: Memoized
const getTotal = useMemo(() => {
return items.reduce((sum, item) => sum + item.price * item.quantity, 0);
}, [items]);
```
### Memory Optimization
**Problem: Memory Leak**
```javascript
// Bad: Event listener not cleaned up
useEffect(() => {
window.addEventListener('scroll', handleScroll);
// Memory leak!
}, []);
// Good: Cleanup
useEffect(() => {
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, []);
```
**Problem: Large Data in Memory**
```javascript
// Bad: Loads entire file into memory
const data = fs.readFileSync('huge-file.txt'); // 1GB
// Good: Stream it
const stream = fs.createReadStream('huge-file.txt');
stream.on('data', chunk => process(chunk));
```
## Measuring Impact
Always measure before and after:
```javascript
// Before optimization
console.time('query');
const users = await db.users.find();
console.timeEnd('query');
// query: 2341ms
// After optimization (added index)
console.time('query');
const users = await db.users.find();
console.timeEnd('query');
// query: 23ms
// Improvement: 100x faster!
```
## Performance Budgets
Set targets:
```
Page Load: < 2 seconds
API Response: < 200ms
Database Query: < 50ms
Bundle Size: < 200KB
Time to Interactive: < 3 seconds
```
## Tools
**Browser:**
- Chrome DevTools Performance tab
- Lighthouse (audit)
- Network tab (waterfall)
**Node.js:**
- `node --prof` (profiling)
- `clinic` (diagnostics)
- `autocannon` (load testing)
**Database:**
- `EXPLAIN ANALYZE` (query plans)
- Slow query log
- Database profiler
**Monitoring:**
- New Relic
- Datadog
- Sentry Performance
## Quick Wins
Easy optimizations with big impact:
1. **Add database indexes** on frequently queried columns
2. **Enable gzip compression** on server
3. **Add caching** for expensive operations
4. **Lazy load** images and heavy components
5. **Use CDN** for static assets
6. **Minify and compress** JavaScript/CSS
7. **Remove unused dependencies**
8. **Use pagination** instead of loading all data
9. **Optimize images** (WebP, proper sizing)
10. **Enable HTTP/2** on server
## Optimization Checklist
- [ ] Measured current performance
- [ ] Identified bottleneck
- [ ] Applied optimization
- [ ] Measured improvement
- [ ] Verified functionality still works
- [ ] No new bugs introduced
- [ ] Documented the change
## When NOT to Optimize
- Premature optimization (optimize when it's actually slow)
- Micro-optimizations (save 1ms when page takes 5 seconds)
- Readable code is more important than tiny speed gains
- If it's already fast enough
## Key Principles
- Measure before optimizing
- Fix the biggest bottleneck first
- Measure after to prove improvement
- Don't sacrifice readability for tiny gains
- Profile in production-like environment
- Consider the 80/20 rule (20% of code causes 80% of slowness)
## Related Skills
- `@database-design` - Query optimization
- `@codebase-audit-pre-push` - Code review
- `@bug-hunter` - Debugging
Source: claude-code-templates (MIT). See About Us for full credits.