Claude
Skills
Sign in
Back

remotion-performance-optimizer

Included with Lifetime
$97 forever

Analyzes Remotion compositions for performance issues and provides optimization recommendations. Identifies expensive computations, unnecessary re-renders, large assets, memoization opportunities, and architecture improvements. Use when optimizing render times or when asked to "improve performance", "speed up renders", "optimize Remotion video".

Image & Video

What this skill does


# Remotion Performance Optimizer

Comprehensive performance analysis and optimization recommendations for Remotion video compositions. Identifies bottlenecks and provides actionable fixes to reduce render times.

## What This Skill Does

Performs deep performance analysis:

1. **Computation analysis** — Identify expensive operations in render path
2. **Re-render detection** — Find unnecessary component re-renders
3. **Asset optimization** — Recommend asset size and format improvements
4. **Memoization opportunities** — Identify cacheable calculations
5. **Architecture review** — Suggest structural improvements
6. **Render profiling** — Analyze frame render times

## Input/Output Formats

### Input Format: Remotion Composition Code

Accepts implemented Remotion composition files:

**Files to analyze:**
```
src/remotion/compositions/VideoName/
├── index.tsx           # Main composition
├── constants.ts        # Color, timing, spring configs
├── types.ts            # TypeScript types
└── scenes/
    ├── Scene1.tsx
    ├── Scene2.tsx
    └── Scene3.tsx
```

**Context needed:**
- Target render time goals (e.g., < 100ms/frame)
- Composition complexity (simple, moderate, complex)
- Any specific performance concerns

**Example request:**
```
Analyze performance of VideoName composition.
Target: < 100ms/frame average render time.
Scene 2 is rendering slowly (200ms/frame).
```

### Output Format: OPTIMIZATION_REPORT.md

Generates detailed performance analysis with actionable fixes:

```markdown
# Performance Optimization Report: [Video Title]

**Date:** 2026-01-23
**Analyzer:** remotion-performance-optimizer
**Composition:** `src/remotion/compositions/VideoName/`

---

## Executive Summary

**Current Performance:** ⚠️ NEEDS OPTIMIZATION

| Metric | Current | Target | Status |
|--------|---------|--------|--------|
| **Average Render Time** | 145ms/frame | < 100ms | 🔴 45% over target |
| **Slowest Scene** | Scene 2: 285ms | < 150ms | 🔴 90% over target |
| **Total Render Time (estimated)** | 36 minutes | < 20 minutes | 🔴 80% over target |
| **Memory Usage** | Normal | Normal | 🟢 Good |

**Potential Improvement:** 60-70% faster render times after implementing recommendations

**Priority Actions:**
1. Replace Math.random() with seeded random in Scene 2 (55% improvement)
2. Optimize large product image (20% faster asset loading)
3. Extract repeated spring calculations (15% improvement)

---

## Performance Breakdown by Scene

| Scene | Avg Render Time | Status | Primary Bottleneck |
|-------|----------------|--------|-------------------|
| Scene 1 | 75ms | 🟢 Good | None |
| Scene 2 | 285ms | 🔴 Critical | Non-deterministic particle system |
| Scene 3 | 95ms | 🟡 Acceptable | Large asset loading |
| Scene 4 | 80ms | 🟢 Good | None |

**Overall:** 145ms average (Target: < 100ms)

---

## Issues Found

### CRITICAL (Major Performance Impact)

#### 1. Non-Deterministic Particle System in Scene 2
**Impact:** 🔴 200ms per frame slowdown
**Location:** `src/remotion/compositions/VideoName/scenes/Scene2.tsx:48-65`
**Severity:** Critical - 70% of render time in Scene 2

**Problem:**
```typescript
// ❌ PROBLEM: Math.random() called 70 times per frame
{Array.from({ length: 70 }, (_, i) => {
  const x = Math.random() * width;     // Recalculated every frame!
  const y = Math.random() * height;    // Non-deterministic
  const speed = Math.random() * 2;

  return <Particle key={i} x={x} y={y} speed={speed} />;
})}
```

**Why This Is Slow:**
- Math.random() is non-deterministic (different each frame)
- 70 particles × 3 random calls = 210 random calls per frame
- Remotion can't cache because values change
- Browser must recalculate positions every frame

**Solution:**
```typescript
// ✅ OPTIMIZED: Seeded random, deterministic
const seededRandom = (seed: number): number => {
  const x = Math.sin(seed) * 10000;
  return x - Math.floor(x);
};

const particles = useMemo(
  () => Array.from({ length: 70 }, (_, i) => ({
    x: seededRandom(i * 123.456) * width,
    y: seededRandom(i * 789.012) * height,
    speed: seededRandom(i * 456.789) * 2,
  })),
  [width, height]
);

{particles.map((p, i) => (
  <Particle key={i} x={p.x} y={p.y} speed={p.speed} />
))}
```

**Expected Improvement:**
- Scene 2: 285ms → 125ms (55% faster)
- Overall: 145ms → 105ms (28% faster)
- Total render time: 36min → 22min (40% faster)

**Implementation Time:** 15 minutes

---

### HIGH (Significant Performance Impact)

#### 2. Large Unoptimized Product Image
**Impact:** 🟡 50ms asset loading delay
**Location:** `public/images/product.png`
**Severity:** High - Affects loading and memory

**Problem:**
```
Current Asset:
- Format: PNG (unnecessary transparency)
- Resolution: 4000x3000 (2x larger than needed)
- File Size: 8.2MB
- Load Time: ~50ms
```

**Why This Is Slow:**
- 8.2MB file takes time to load and decode
- 4000x3000 is overkill for 1920x1080 display
- PNG format unnecessary (no transparency used)

**Solution:**
```bash
# Resize and convert to JPEG
magick public/images/product.png \
  -resize 1920x1440 \
  -quality 90 \
  public/images/product.jpg

# Update code
<Img src={staticFile('images/product.jpg')} />
```

**Result:**
```
Optimized Asset:
- Format: JPEG
- Resolution: 1920x1440 (2x for retina)
- File Size: ~400KB (95% smaller)
- Load Time: ~5ms (90% faster)
```

**Expected Improvement:**
- Scene 3 load time: 50ms faster
- Overall render: 95ms → 85ms in Scene 3
- Smaller final video file

**Implementation Time:** 5 minutes

---

#### 3. Repeated Spring Calculations
**Impact:** 🟡 30ms per scene
**Location:** Multiple scenes
**Severity:** High - Accumulates across scenes

**Problem in Scene 1:**
```typescript
// ❌ PROBLEM: Spring calculated 3 times
<div style={{
  opacity: spring({ frame, fps, config: SMOOTH }),
  scale: spring({ frame, fps, config: SMOOTH }),
  y: interpolate(spring({ frame, fps, config: SMOOTH }), [0, 1], [0, 100]),
}} />
```

**Why This Is Slow:**
- Spring function has internal calculations
- Called 3 times with identical parameters
- Remotion can't optimize duplicate calls
- Wastes 20-30ms per scene

**Solution:**
```typescript
// ✅ OPTIMIZED: Calculate once, reuse
const progress = spring({ frame, fps, config: SMOOTH });

<div style={{
  opacity: progress,
  scale: progress,
  y: interpolate(progress, [0, 1], [0, 100]),
}} />
```

**Expected Improvement:**
- Per scene: 20-30ms faster
- Overall: 145ms → 125ms (15% faster)
- Affects Scenes 1, 3, 4

**Implementation Time:** 10 minutes

---

### MEDIUM (Moderate Performance Impact)

#### 4. Component Not Memoized
**Impact:** 🟡 10-15ms
**Location:** Scene components
**Severity:** Medium - Minor unnecessary re-renders

**Problem:**
```typescript
// Scene components re-render even when props haven't changed
function Scene1() { ... }
function Scene2() { ... }
```

**Solution:**
```typescript
import { memo } from 'react';

const Scene1 = memo(() => { ... });
const Scene2 = memo(() => { ... });
```

**Expected Improvement:**
- 10-15ms per scene
- Overall: 10% faster in complex compositions

**Implementation Time:** 5 minutes

---

### LOW (Minor Performance Impact)

#### 5. Array Creation in Render
**Impact:** 🟢 2-5ms
**Location:** `Scene4.tsx:23`
**Severity:** Low - Negligible but fixable

**Problem:**
```typescript
// Array recreated every frame
{Array(50).fill(0).map((_, i) => <Element key={i} />)}
```

**Solution:**
```typescript
// Reuse array reference
const ELEMENTS = Array.from({ length: 50 }, (_, i) => i);

{ELEMENTS.map((i) => <Element key={i} />)}
```

**Expected Improvement:** 2-5ms (minimal but good practice)

**Implementation Time:** 2 minutes

---

## Optimization Implementation Plan

### Phase 1: Critical Fixes (15 minutes) — 55% improvement
1. Replace Math.random() with seeded random in Scene 2
   - Expected: 285ms → 125ms

### Phase 2: High Priority (15 minutes) — 20% additional improvement
1. Optimize product.png to JPEG (5 min)
   - Expected: 95ms → 85ms in Scene 3
2. Extract spring calculations (10 min)
   - Exp

Related in Image & Video