| name | remotion-performance-optimizer |
| description | 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". |
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:
- Computation analysis — Identify expensive operations in render path
- Re-render detection — Find unnecessary component re-renders
- Asset optimization — Recommend asset size and format improvements
- Memoization opportunities — Identify cacheable calculations
- Architecture review — Suggest structural improvements
- 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:
# 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:
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:
magick public/images/product.png \
-resize 1920x1440 \
-quality 90 \
public/images/product.jpg
<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:
<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:
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:
function Scene1() { ... }
function Scene2() { ... }
Solution:
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:
{Array(50).fill(0).map((_, i) => <Element key={i} />)}
Solution:
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
- Replace Math.random() with seeded random in Scene 2
Phase 2: High Priority (15 minutes) — 20% additional improvement
- Optimize product.png to JPEG (5 min)
- Expected: 95ms → 85ms in Scene 3
- Extract spring calculations (10 min)
- Expected: 145ms → 125ms overall
Phase 3: Medium Priority (10 minutes) — 10% additional improvement
- Memoize scene components
- Expected: 10-15ms improvement
Phase 4: Low Priority (5 minutes) — 2-5% improvement
- Extract array constants
- Expected: 2-5ms improvement
Total Implementation Time: 45 minutes
Total Expected Improvement: 60-70% faster renders
Before/After Projections
| Metric | Before | After Phase 1 | After Phase 2 | After All | Target |
|---|
| Scene 2 | 285ms | 125ms | 115ms | 110ms | < 150ms ✅ |
| Scene 3 | 95ms | 95ms | 85ms | 80ms | < 100ms ✅ |
| Overall Avg | 145ms | 105ms | 90ms | 85ms | < 100ms ✅ |
| Total Render | 36min | 22min | 19min | 18min | < 20min ✅ |
After all optimizations: All targets met! 🎉
Performance Validation
Benchmarking Commands
npx remotion still src/index.tsx VideoName --frame=150
npx remotion still src/index.tsx VideoName --frame=225
time npx remotion render src/index.tsx VideoName test.mp4 --frames=0-100
time npx remotion render src/index.tsx VideoName output.mp4
Performance Targets
| Composition Type | Target | Current | Status |
|---|
| Simple scenes | < 50ms | 75ms (Scenes 1,4) | 🟡 Acceptable |
| Moderate scenes | < 100ms | 145ms avg | 🔴 Over target |
| Complex scenes | < 150ms | 285ms (Scene 2) | 🔴 Over target |
After optimizations: All scenes should meet targets
Code Quality Checks
✅ Good Patterns Found:
- Constants extracted (COLORS, SPRING_CONFIGS)
- useVideoConfig used for responsive sizing
- TypeScript types defined
- staticFile() used for assets
⚠️ Optimization Opportunities:
Asset Optimization Details
Current Assets
| Asset | Size | Format | Status | Recommendation |
|---|
| logo.png | 180KB | PNG | 🟢 Good | Keep as-is |
| product.png | 8.2MB | PNG | 🔴 Optimize | → JPEG 400KB |
| background.mp3 | 1.8MB | MP3 | 🟢 Good | Keep as-is |
| whoosh.mp3 | 45KB | MP3 | 🟢 Good | Keep as-is |
Optimization Commands
magick public/images/product.png \
-resize 1920x1440 \
-quality 90 \
public/images/product.jpg
Recommendations Summary
Immediate Actions (Critical)
- ✅ Replace Math.random() in Scene 2 — 55% faster
- Priority: CRITICAL
- Time: 15 minutes
- Impact: 160ms per frame improvement
Short-Term Actions (High Priority)
-
✅ Optimize product image — 20% faster loading
- Priority: HIGH
- Time: 5 minutes
- Impact: 50ms improvement
-
✅ Extract spring calculations — 15% faster
- Priority: HIGH
- Time: 10 minutes
- Impact: 20-30ms per scene
Long-Term Improvements (Medium/Low)
- Memoize scene components (10% improvement)
- Extract array constants (2-5% improvement)
- Consider lazy loading assets
- Profile with Chrome DevTools for deeper analysis
Next Steps
- Implement Critical Fix: Replace Math.random() (highest impact)
- Benchmark: Verify Scene 2 improvement (should be 285ms → 125ms)
- Implement High Priority: Optimize assets and springs
- Re-run analysis: Verify all targets met
- Final render: Generate production video with optimizations
Tools & Resources
Profiling Tools
npx remotion preview --log=verbose
Optimization References
Approval
Status: ⚠️ OPTIMIZATION REQUIRED BEFORE PRODUCTION
After implementing critical and high-priority fixes, this composition will meet all performance targets and be production-ready.
Estimated Time to Production-Ready: 30-45 minutes of optimization work
Signed: remotion-performance-optimizer
Date: 2026-01-23
**This document provides:**
- Current vs. target performance metrics
- Prioritized issues by impact (CRITICAL, HIGH, MEDIUM, LOW)
- Before/after projections with concrete numbers
- Specific code locations and fixes
- Implementation time estimates
- Step-by-step optimization plan
- Benchmarking commands for validation
- Asset optimization recommendations
**Feeds into:**
- Developer: Implement fixes
- Re-run `/remotion-video-reviewer` after optimizations
- Final production render
## Performance Analysis Categories
### 1. Expensive Computations
**Issue:** Calculations executed every frame unnecessarily.
**Detection:**
```typescript
// ❌ PROBLEM - Recalculated every frame
function Scene() {
const frame = useCurrentFrame();
// Heavy calculation every frame
const particles = Array.from({ length: 1000 }, () => ({
x: Math.random() * 1920,
y: Math.random() * 1080,
}));
return /* render particles */;
}
Solution:
function Scene() {
const frame = useCurrentFrame();
const particles = useMemo(
() => Array.from({ length: 1000 }, (_, i) => ({
x: seededRandom(i * 123) * 1920,
y: seededRandom(i * 456) * 1080,
})),
[]
);
return ;
}
const seededRandom = (seed: number) => {
const x = Math.sin(seed) * 10000;
return x - Math.floor(x);
};
Impact: 30-50% render time reduction for scenes with many elements.
2. Repeated Spring Calculations
Issue: Same spring calculation multiple times.
Detection:
<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]),
}} />
Solution:
const progress = spring({ frame, fps, config: SMOOTH });
<div style={{
opacity: progress,
scale: progress,
y: interpolate(progress, [0, 1], [0, 100]),
}} />
Impact: 10-20% render time reduction per scene.
3. Large Asset Sizes
Issue: Unoptimized assets slow down loading and rendering.
Detection:
Product image: 4000x3000 PNG (8.2MB)
Background video: 3840x2160 ProRes (450MB)
Logo: 2000x2000 PNG (1.5MB)
Recommendations:
✓ Product image: 1920x1440 JPEG 90% (400KB) — 95% smaller
✓ Background video: 1920x1080 H.264 (25MB) — 95% smaller
✓ Logo: 800x800 PNG optimized (80KB) — 95% smaller
Impact: Faster renders, smaller output files, better preview performance.
4. Unnecessary Re-renders
Issue: Components re-render when dependencies haven't changed.
Detection:
function ExpensiveComponent({ data }) {
const processed = data.map(item => );
return ;
}
<ExpensiveComponent data={staticData} />
Solution:
const ExpensiveComponent = memo(({ data }) => {
const processed = useMemo(
() => data.map(item => ),
[data]
);
return ;
});
const processedData = staticData.map(item => );
function Scene() {
return <Component data={processedData} />;
}
Impact: 20-40% render time reduction for complex components.
5. DOM Thrashing
Issue: Excessive DOM reads/writes causing layout thrashing.
Detection:
elements.forEach((el) => {
const width = el.getBoundingClientRect().width;
el.style.width = `${width * 2}px`;
});
Solution:
const widths = elements.map((el) => el.getBoundingClientRect().width);
elements.forEach((el, i) => {
el.style.width = `${widths[i] * 2}px`;
});
Impact: 15-30% improvement in DOM-heavy scenes.
6. Unoptimized Loops
Issue: Inefficient iteration patterns.
Detection:
{Array(100).fill(0).map((_, i) => (
<Particle key={i} index={i} />
))}
Solution:
const PARTICLES = Array.from({ length: 100 }, (_, i) => i);
{PARTICLES.map((i) => (
<Particle key={i} index={i} />
))}
Impact: 5-10% improvement in scenes with many elements.
Performance Optimization Checklist
Computation Optimizations
Component Optimizations
Asset Optimizations
Render Optimizations
Architecture Optimizations
Performance Benchmarking
Measuring Render Time
npx remotion still src/index.tsx VideoName --frame=100
time npx remotion render src/index.tsx VideoName output.mp4 --frames=0-100
npx remotion preview
Performance Targets
| Composition Type | Target Render Time | Notes |
|---|
| Simple (text, shapes) | < 50ms/frame | Minimal computations |
| Moderate (animations, images) | 50-100ms/frame | Standard videos |
| Complex (particles, 3D) | 100-200ms/frame | Heavy effects |
| Very Complex (thousands of elements) | 200-500ms/frame | Acceptable with optimization |
Red flags:
- Single frame > 500ms → Major optimization needed
- Render time increases over time → Memory leak
Common Bottleneck Patterns
Pattern 1: Particle Explosion
Issue:
{Array(1000).fill(0).map((_, i) => {
const x = Math.random() * width;
const y = Math.random() * height;
return <Particle key={i} x={x} y={y} />;
})}
Fix:
const particles = useMemo(
() => Array.from({ length: 1000 }, (_, i) => ({
x: seededRandom(i * 123.456) * width,
y: seededRandom(i * 789.012) * height,
})),
[width, height]
);
{particles.map((p, i) => (
<Particle key={i} x={p.x} y={p.y} />
))}
Pattern 2: Text Processing
Issue:
const words = text.split(' ');
const processed = words.map(w => w.toUpperCase());
Fix:
const processedWords = useMemo(
() => text.split(' ').map(w => w.toUpperCase()),
[text]
);
Pattern 3: Conditional Rendering
Issue:
<HeavyComponent style={{ opacity: frame > 100 ? 1 : 0 }} />
Fix:
{frame > 100 && <HeavyComponent />}
Optimization Report Template
## Performance Optimization Report
### Current Performance
- Average render time: 180ms/frame
- Slowest scene: Scene 3 (350ms/frame)
- Total video render time: 45 minutes (estimated)
### Identified Issues
**CRITICAL (Major Impact)**
1. Particle system using Math.random()
- Location: Scene 2, ParticleSystem component
- Impact: +200ms per frame
- Fix: Replace with seeded random
- Estimated improvement: 55% faster
2. 4K product image not optimized
- Location: Scene 4
- Current: 8.2MB PNG
- Impact: Slow loading, memory pressure
- Fix: Resize to 1920x1440, convert to JPEG
- Estimated improvement: 95% smaller file
**HIGH (Significant Impact)**
1. Repeated spring calculations
- Location: Scene 1, Scene 3, Scene 5
- Impact: +50ms per scene
- Fix: Extract to progress variable
- Estimated improvement: 20% faster
**MEDIUM (Moderate Impact)**
1. Components not memoized
- Location: Scene components
- Fix: Wrap in React.memo()
- Estimated improvement: 10% faster
### Optimization Plan
1. Implement seeded random (15 min) — 55% improvement
2. Optimize assets (30 min) — Better loading
3. Extract spring calculations (10 min) — 20% improvement
4. Memoize components (20 min) — 10% improvement
**Expected Result:**
- Render time: 180ms → 80ms per frame (55% faster)
- Total render: 45 min → 20 min
Integration with Other Skills
Works with:
/remotion-video-reviewer — Performance audit during review
/remotion-best-practices — Ensures optimized patterns
/remotion-spec-translator — Generates optimized code from start
Rules Directory
Detailed optimization guides:
This skill ensures Remotion videos render as fast as possible while maintaining quality.