Claude
Skills
Sign in
Back

optimize

Included with Lifetime
$97 forever

Optimize code for performance, readability, or efficiency

General

What this skill does


# Performance Optimization Skill

Systematic approach to identifying and fixing performance issues.

## Name

han-core:optimize - Optimize code for performance, readability, or efficiency

## Synopsis

```
/optimize [arguments]
```

## Core Principle

**Measure, don't guess.** Optimization without data is guesswork.

## The Cardinal Rule

**NEVER optimize without measuring first**

**Why:** Premature optimization wastes time on non-issues while missing real problems.

**Exception:** Obvious O(n^2) algorithms when O(n) alternatives exist.

## Optimization Process

### 1. Measure Current State (Baseline)

**Before touching any code, establish metrics:**

**Frontend Performance:**

```bash
# Chrome DevTools Performance tab
# Lighthouse audit
npm run build && du -sh dist/  # Bundle size
```

**Backend Performance:**

```bash
# Add timing logs
start = Time.now
result = expensive_operation()
elapsed = Time.now - start
Logger.info("Operation took #{elapsed}ms")
```

**Database:**

```bash
# PostgreSQL
EXPLAIN ANALYZE SELECT ...;

# Check query time in logs
grep "SELECT" logs/production.log | grep "Duration:"
```

**Metrics to capture:**

- Load time / response time
- Time to interactive
- Bundle size
- Memory usage
- Query duration
- Render time

### 2. Profile to Find Bottlenecks

**Don't guess where the problem is - profile:**

**Browser Profiling:**

- Chrome DevTools > Performance tab
- Record interaction
- Look for long tasks (> 50ms)
- Check for layout thrashing

**Server Profiling:**

```bash
# Add detailed timing
defmodule Profiler do
  def measure(label, func) do
    start = System.monotonic_time(:millisecond)
    result = func.()
    elapsed = System.monotonic_time(:millisecond) - start
    Logger.info("#{label}: #{elapsed}ms")
    result
  end
end

# Use it
Profiler.measure("Database query", fn ->
  Repo.all(User)
end)
```

**React Profiling:**

```bash
# React DevTools Profiler
# Look for:
# - Unnecessary re-renders
# - Slow components (> 16ms for 60fps)
# - Large component trees
```

### 3. Identify Root Cause

**Common performance issues:**

**Frontend:**

- Large bundle size (lazy load, code split)
- Unnecessary re-renders (memoization)
- Blocking JavaScript (defer, async)
- Unoptimized images (WebP, lazy loading)
- Too many network requests (bundle, cache)
- Memory leaks (cleanup useEffect)

**Backend:**

- N+1 queries (preload associations)
- Missing database indexes
- Expensive computations in loops
- Synchronous external API calls
- Large JSON responses
- Inefficient algorithms

**Database:**

- Missing indexes
- Inefficient query structure
- Too many joins
- Fetching unnecessary columns
- No query result caching

### 4. Apply Targeted Optimization

**One change at a time** - Measure impact of each change

#### Frontend Optimizations

**Bundle Size Reduction:**

```typescript
// Before: Import entire library
import _ from 'lodash'

// After: Import only what's needed
import debounce from 'lodash/debounce'

// Or: Use native alternatives
const unique = [...new Set(array)]  // Instead of _.uniq(array)
```

**React Performance:**

```typescript
// Before: Re-renders on every parent render
function ChildComponent({ items }) {
  return <div>{items.map(...)}</div>
}

// After: Only re-render when items change
const ChildComponent = React.memo(function ChildComponent({ items }) {
  return <div>{items.map(...)}</div>
}, (prev, next) => prev.items === next.items)

// Before: Recreates function every render
function Parent() {
  const handleClick = () => { ... }
  return <Child onClick={handleClick} />
}

// After: Stable function reference
function Parent() {
  const handleClick = useCallback(() => { ... }, [])
  return <Child onClick={handleClick} />
}
```

**Code Splitting:**

```typescript
// Before: All in main bundle
import HeavyComponent from './HeavyComponent'

// After: Lazy load when needed
const HeavyComponent = React.lazy(() => import('./HeavyComponent'))

function App() {
  return (
    <Suspense fallback={<Loading />}>
      <HeavyComponent />
    </Suspense>
  )
}
```

**Image Optimization:**

```typescript
// Before: Full-size image
<img src="/hero.jpg" />

// After: Responsive, lazy-loaded
<img
  src="/hero-800w.webp"
  srcSet="/hero-400w.webp 400w, /hero-800w.webp 800w"
  loading="lazy"
  alt="Hero image"
/>
```

#### Backend Optimizations

**N+1 Query Fix:**

```elixir
# Before: N+1 queries (1 for users + N for posts)
users = Repo.all(User)
Enum.map(users, fn user ->
  posts = Repo.all(from p in Post, where: p.user_id == ^user.id)
  {user, posts}
end)

# After: 2 queries total
users = Repo.all(User) |> Repo.preload(:posts)
Enum.map(users, fn user -> {user, user.posts} end)
```

**Database Indexing:**

```sql
-- Before: Slow query
SELECT * FROM users WHERE email = '[email protected]';
-- Seq Scan (5000ms)

-- After: Add index
CREATE INDEX idx_users_email ON users(email);
-- Index Scan (2ms)
```

**Caching:**

```elixir
# Before: Expensive calculation every request
def get_popular_posts do
  # Complex aggregation query (500ms)
  Repo.all(from p in Post, ...)
end

# After: Cache for 5 minutes
def get_popular_posts do
  Cachex.fetch(:app_cache, "popular_posts", fn ->
    result = Repo.all(from p in Post, ...)
    {:commit, result, ttl: :timer.minutes(5)}
  end)
end
```

**Batch Processing:**

```elixir
# Before: Process one at a time
Enum.each(user_ids, fn id ->
  user = Repo.get(User, id)
  send_email(user)
end)

# After: Batch fetch
users = Repo.all(from u in User, where: u.id in ^user_ids)
Enum.each(users, &send_email/1)
```

#### Algorithm Optimization

**Reduce Complexity:**

```typescript
// Before: O(n^2) - nested loops
function findDuplicates(arr: number[]): number[] {
  const duplicates = []
  for (let i = 0; i < arr.length; i++) {
    for (let j = i + 1; j < arr.length; j++) {
      if (arr[i] === arr[j] && !duplicates.includes(arr[i])) {
        duplicates.push(arr[i])
      }
    }
  }
  return duplicates
}

// After: O(n) - single pass with Set
function findDuplicates(arr: number[]): number[] {
  const seen = new Set<number>()
  const duplicates = new Set<number>()

  for (const num of arr) {
    if (seen.has(num)) {
      duplicates.add(num)
    }
    seen.add(num)
  }

  return Array.from(duplicates)
}
```

### 5. Measure Impact (Proof of Work)

**ALWAYS measure after optimization:**

```markdown
## Optimization: [What was changed]

### Before
- Load time: 3.2s
- Bundle size: 850KB
- Time to interactive: 4.1s

### Changes
- Lazy loaded HeavyComponent
- Switched to lodash-es for tree shaking
- Added React.memo to ProductList

### After
- Load time: 1.8s (-44%)
- Bundle size: 520KB (-39%)
- Time to interactive: 2.3s (-44%)

### Evidence
```

```bash
# Before
$ npm run build
dist/main.js   850.2 KB

# After
$ npm run build
dist/main.js   520.8 KB
```

**Use proof-of-work skill to document evidence**

### 6. Verify Correctness

**Tests must still pass:**

```bash
# Run full test suite
npm test        # Frontend
mix test        # Backend

# Manual verification
# - Feature still works
# - Edge cases handled
# - No new bugs introduced
```

## Optimization Types

**Performance:**

- Algorithm complexity reduction
- Database query optimization
- Caching strategies
- Lazy loading and code splitting

**Code Quality:**

- Simplification and clarity
- Removing duplication
- Better naming and structure
- Pattern improvements

**Resource Efficiency:**

- Memory usage reduction
- Bundle size optimization
- Network request reduction
- Asset optimization

## Common Optimization Targets

### Frontend Checklist

- [ ] Bundle size < 200KB (gzipped)
- [ ] First Contentful Paint < 1.5s
- [ ] Time to Interactive < 3s
- [ ] No layout shift (CLS < 0.1)
- [ ] Images optimized (WebP, lazy loading)
- [ ] Code split by route
- [ ] Unused code removed (tree shaking)
- [ ] CSS critical path optimized

### Backend Checklist

- [ ] API response time < 200ms (p95)
- [ ] Database queries optimized (EXPLAIN ANALYZE)
- [ ] No N+1 queries
- [ ] Appropriat

Related in General