remotion-performance-optimizer

安装量: 48
排名: #15422

安装

npx skills add https://github.com/ncklrs/startup-os-skills --skill remotion-performance-optimizer

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 ; })}

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:

// ✅ 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) => ( ))}

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:

Resize and convert to JPEG

magick public/images/product.png \ -resize 1920x1440 \ -quality 90 \ public/images/product.jpg

Update code

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

  1. Repeated Spring Calculations

Impact: 🟡 30ms per scene Location: Multiple scenes Severity: High - Accumulates across scenes

Problem in Scene 1:

// ❌ PROBLEM: Spring calculated 3 times

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:

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

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:

// Scene components re-render even when props haven't changed 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 recreated every frame

Solution:

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

{ELEMENTS.map((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 Expected: 285ms → 125ms 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

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

Product image (95% size reduction)

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

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:

// ✓ 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.

  1. Repeated Spring Calculations

Issue: Same spring calculation multiple times.

Detection:

// ❌ PROBLEM - Spring calculated 3 times

Solution:

// ✓ OPTIMIZED - Calculate once, reuse const progress = spring({ frame, fps, config: SMOOTH });

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

  1. 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.

  1. Unnecessary Re-renders

Issue: Components re-render when dependencies haven't changed.

Detection:

// ❌ 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

Solution:

// ✓ 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 ; }

Impact: 20-40% render time reduction for complex components.

  1. DOM Thrashing

Issue: Excessive DOM reads/writes causing layout thrashing.

Detection:

// ❌ 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:

// ✓ 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.

  1. Unoptimized Loops

Issue: Inefficient iteration patterns.

Detection:

// ❌ PROBLEM - Array creation every frame {Array(100).fill(0).map((_, i) => ( ))}

Solution:

// ✓ OPTIMIZED - Reuse array reference const PARTICLES = Array.from({ length: 100 }, (_, i) => i);

{PARTICLES.map((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

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:

// 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 ; })}

Fix:

// 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) => ( ))}

Pattern 2: Text Processing

Issue:

// String operations every frame const words = text.split(' '); const processed = words.map(w => w.toUpperCase());

Fix:

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

Pattern 3: Conditional Rendering

Issue:

// Component always rendered, visibility toggled 100 ? 1 : 0 }} />

Fix:

// Don't render at all when not visible

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

  1. 4K product image not optimized
  2. Location: Scene 4
  3. Current: 8.2MB PNG
  4. Impact: Slow loading, memory pressure
  5. Fix: Resize to 1920x1440, convert to JPEG
  6. 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 — Optimizing calculations rules/asset-optimization.md — Asset size and format rules/memoization-strategies.md — When and how to memoize rules/render-optimization.md — Render path improvements

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

返回排行榜