home / skills / ncklrs / startup-os-skills / remotion-performance-optimizer

remotion-performance-optimizer skill

/skills/remotion-performance-optimizer

This skill analyzes Remotion compositions to identify bottlenecks and provides actionable performance optimizations for faster renders.

npx playbooks add skill ncklrs/startup-os-skills --skill remotion-performance-optimizer

Review the files below or copy the command above to add this skill to your agents.

Files (2)
SKILL.md
22.9 KB
---
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:

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)
   - Expected: 145ms → 125ms overall

### Phase 3: Medium Priority (10 minutes) — 10% additional improvement
1. Memoize scene components
   - Expected: 10-15ms improvement

### Phase 4: Low Priority (5 minutes) — 2-5% improvement
1. 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

```bash
# Test single frame render time
npx remotion still src/index.tsx VideoName --frame=150

# Profile specific scene (Scene 2)
npx remotion still src/index.tsx VideoName --frame=225

# Benchmark full render (first 100 frames)
time npx remotion render src/index.tsx VideoName test.mp4 --frames=0-100

# Full production render with timing
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:**
- [ ] Replace Math.random() with seeded random
- [ ] Extract repeated spring calculations
- [ ] Memoize scene components
- [ ] Optimize large assets

---

## 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

```bash
# Product image (95% size reduction)
magick public/images/product.png \
  -resize 1920x1440 \
  -quality 90 \
  public/images/product.jpg
```

---

## Recommendations Summary

### Immediate Actions (Critical)
1. ✅ **Replace Math.random() in Scene 2** — 55% faster
   - Priority: CRITICAL
   - Time: 15 minutes
   - Impact: 160ms per frame improvement

### Short-Term Actions (High Priority)
1. ✅ **Optimize product image** — 20% faster loading
   - Priority: HIGH
   - Time: 5 minutes
   - Impact: 50ms improvement

2. ✅ **Extract spring calculations** — 15% faster
   - Priority: HIGH
   - Time: 10 minutes
   - Impact: 20-30ms per scene

### Long-Term Improvements (Medium/Low)
1. Memoize scene components (10% improvement)
2. Extract array constants (2-5% improvement)
3. Consider lazy loading assets
4. Profile with Chrome DevTools for deeper analysis

---

## Next Steps

1. **Implement Critical Fix:** Replace Math.random() (highest impact)
2. **Benchmark:** Verify Scene 2 improvement (should be 285ms → 125ms)
3. **Implement High Priority:** Optimize assets and springs
4. **Re-run analysis:** Verify all targets met
5. **Final render:** Generate production video with optimizations

---

## Tools & Resources

### Profiling Tools
```bash
# Remotion built-in profiling
npx remotion preview --log=verbose

# Chrome DevTools profiling
# Open preview → DevTools → Performance tab → Record
```

### Optimization References
- Remotion Performance Docs: https://remotion.dev/docs/performance
- React Profiler: https://react.dev/reference/react/Profiler
- Seeded Random Pattern: See `/remotion-component-builder` skill

---

## 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:**
```typescript
// ✓ OPTIMIZED - Deterministic, seeded
function Scene() {
  const frame = useCurrentFrame();

  // Deterministic calculation
  const particles = useMemo(
    () => Array.from({ length: 1000 }, (_, i) => ({
      x: seededRandom(i * 123) * 1920,
      y: seededRandom(i * 456) * 1080,
    })),
    [] // No dependencies, calculate once
  );

  return /* render particles */;
}

// Seeded random for consistency
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:**
```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]),
}} />
```

**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]),
}} />
```

**Impact:** 10-20% render time reduction per scene.

### 3. Large Asset Sizes

**Issue:** Unoptimized assets slow down loading and rendering.

**Detection:**
```markdown
Product image: 4000x3000 PNG (8.2MB)
Background video: 3840x2160 ProRes (450MB)
Logo: 2000x2000 PNG (1.5MB)
```

**Recommendations:**
```markdown
✓ 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:**
```typescript
// ❌ PROBLEM - Re-renders on every frame change
function ExpensiveComponent({ data }) {
  // Heavy calculation
  const processed = data.map(item => /* complex transform */);

  return /* render */;
}

// Parent re-renders every frame
<ExpensiveComponent data={staticData} />
```

**Solution:**
```typescript
// ✓ OPTIMIZED - Memoized component
const ExpensiveComponent = memo(({ data }) => {
  // Heavy calculation
  const processed = useMemo(
    () => data.map(item => /* complex transform */),
    [data]
  );

  return /* render */;
});

// Or: Extract static data outside component
const processedData = staticData.map(item => /* complex transform */);

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:**
```typescript
// ❌ PROBLEM - Reading and writing in loop
elements.forEach((el) => {
  const width = el.getBoundingClientRect().width; // Read
  el.style.width = `${width * 2}px`; // Write (causes reflow)
});
```

**Solution:**
```typescript
// ✓ OPTIMIZED - Batch reads, then batch writes
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:**
```typescript
// ❌ PROBLEM - Array creation every frame
{Array(100).fill(0).map((_, i) => (
  <Particle key={i} index={i} />
))}
```

**Solution:**
```typescript
// ✓ OPTIMIZED - Reuse array reference
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
- [ ] No Math.random() in render (use seeded random)
- [ ] Heavy calculations use useMemo
- [ ] Spring calculations extracted and reused
- [ ] Static data moved outside components
- [ ] Loops use Array.from instead of Array().fill()

### Component Optimizations
- [ ] Expensive components wrapped in memo()
- [ ] useMemo for derived state
- [ ] useCallback for event handlers passed to children
- [ ] Components split appropriately (not too large)

### Asset Optimizations
- [ ] Images sized to actual display dimensions (2x for retina)
- [ ] JPEG for photos, PNG for transparency, SVG for graphics
- [ ] Videos use H.264 codec with reasonable bitrate
- [ ] Audio files trimmed to exact duration
- [ ] Fonts load only required weights

### Render Optimizations
- [ ] Avoid inline object/array creation in JSX
- [ ] Use key prop correctly in lists
- [ ] Minimize div nesting depth
- [ ] Use CSS transforms over position changes
- [ ] AbsoluteFill instead of complex layouts

### Architecture Optimizations
- [ ] Extract reusable components
- [ ] Scene components under 200 lines
- [ ] Constants extracted to top of file
- [ ] Utility functions outside components
- [ ] Logical component composition

## Performance Benchmarking

### Measuring Render Time

```bash
# Benchmark a specific frame
npx remotion still src/index.tsx VideoName --frame=100

# Benchmark full render (first 100 frames)
time npx remotion render src/index.tsx VideoName output.mp4 --frames=0-100

# Profile with Chrome DevTools
npx remotion preview
# Open Chrome DevTools → Performance tab → Record
```

### 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:**
```typescript
// 1000 particles, each calculating independently
{Array(1000).fill(0).map((_, i) => {
  const x = Math.random() * width;  // Recalculated every frame!
  const y = Math.random() * height;
  return <Particle key={i} x={x} y={y} />;
})}
```

**Fix:**
```typescript
// Deterministic particles, calculated once
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:**
```typescript
// String operations every frame
const words = text.split(' ');
const processed = words.map(w => w.toUpperCase());
```

**Fix:**
```typescript
// Process once outside render
const processedWords = useMemo(
  () => text.split(' ').map(w => w.toUpperCase()),
  [text]
);
```

### Pattern 3: Conditional Rendering

**Issue:**
```typescript
// Component always rendered, visibility toggled
<HeavyComponent style={{ opacity: frame > 100 ? 1 : 0 }} />
```

**Fix:**
```typescript
// Don't render at all when not visible
{frame > 100 && <HeavyComponent />}
```

## Optimization Report Template

```markdown
## 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:

- [rules/computation-optimization.md](rules/computation-optimization.md) — Optimizing calculations
- [rules/asset-optimization.md](rules/asset-optimization.md) — Asset size and format
- [rules/memoization-strategies.md](rules/memoization-strategies.md) — When and how to memoize
- [rules/render-optimization.md](rules/render-optimization.md) — Render path improvements

---

This skill ensures Remotion videos render as fast as possible while maintaining quality.

Overview

This skill analyzes Remotion compositions and produces prioritized, actionable recommendations to reduce render times. It identifies expensive computations, unnecessary re-renders, oversized assets, missing memoization, and architectural hotspots. The output is a clear optimization report with before/after projections and an implementation plan.

How this skill works

I scan composition files and scene components to detect frame-heavy operations, repeated calls (springs, randoms), asset formats and sizes, and memoization gaps. For each issue I provide code-level fixes, estimated impact, and implementation time. The skill also supplies benchmarking commands to validate improvements.

When to use it

  • When render times exceed your target (e.g., >100ms/frame)
  • When asked to “improve performance” or “speed up renders”
  • Before a production render to reduce time and cost
  • When a specific scene shows slow frames
  • When preparing many renders or CI-based builds

Best practices

  • Avoid non-deterministic per-frame computations; use seeded random or useMemo
  • Compute springs or interpolations once and reuse the value across properties
  • Memoize scene components with React.memo to prevent unnecessary re-renders
  • Optimize large images (resize and convert format) and prefer compressed assets for backgrounds
  • Profile iteratively: fix critical issues first, re-benchmark, then apply lower-priority changes

Example use cases

  • Analyze a composition where Scene 2 renders at 285ms/frame and target is <100ms
  • Identify heavy per-frame calculations like Math.random() and replace with seeded deterministic values
  • Shrink and convert a large PNG product image to a JPEG to cut load and decode time
  • Refactor repeated spring() calls into a single computed value to save 20–30ms per scene
  • Provide a prioritized 45-minute implementation plan to reach production-ready performance

FAQ

What inputs do you need?

Provide the composition folder (index.tsx, scenes, constants) and targets (e.g., <100ms/frame), plus any problematic scene notes.

How long to implement fixes?

Most critical fixes are quick: seeded random and memoization ~15 minutes; asset conversion ~5 minutes; full plan ~30–45 minutes.