Benchmarks & Stability
Ember Motion Studio is built for professional broadcast environments where failure is not an option. We measure performance not just in raw speed, but in absolute consistency and resilience. The DVGE engine guarantees that every single frame is frame-perfect.
Rendering Consistency (Determinism)
Section titled “Rendering Consistency (Determinism)”Unlike real-time web engines, the DVGE engine does not use a system clock to calculate animations. Every frame is calculated purely from its discrete index (frame), making temporal drift structurally impossible.
| Engine Type | Timing Method | Result under CPU Load |
|---|---|---|
| Traditional (GSAP / rAF) | System clock (Date.now()) | Dropped frames under heavy CPU load |
| Ember (Frame-Math) | Discrete frame index (ctx.frame) | Identical output on any hardware |
Why drift is zero by design
Section titled “Why drift is zero by design”The engine doesn’t ask “how much time has passed?”. It asks “what does frame number X look like?”. The internal calculateTimeline(frame, fps, durationInFrames) function always produces the exact same result for the same input parameters, regardless of system load or hardware speed.
// Frame 45 of a 120-frame clip ALWAYS produces introProgress = 0.375// On a 2015 laptop or a 2026 workstation. Without exception.update: (ctx) => { refs.title.style.opacity = ctx.timeline.introProgress; // Deterministic}ProRes 4444 Export Performance
Section titled “ProRes 4444 Export Performance”The headless renderer operates with concurrency: 1 — one frame at a time — to guarantee the integrity of the alpha channel in every single frame. These benchmarks reflect this conservative, quality-first configuration.
Test Configuration:
- Resolution: 1920×1080 @ 60 FPS
- Codec: Apple ProRes 4444 (
yuva444p10le, 10-bit) - Concurrency: 1 (by design, for strict alpha integrity)
- Chromium: Headless mode with
--force-cpu-rasterization
| Complexity | Clip Duration | Estimated Export Time |
|---|---|---|
| Simple (Basic Lower Third, text + line) | 5 sec / 300 frames | ~2–4 seconds |
| Medium (News Ticker with scrolling, multiple items) | 10 sec / 600 frames | ~5–8 seconds |
| Complex (Data visualization, heavy CSS filters) | 15 sec / 900 frames | ~10–15 seconds |
Times vary based on hardware. The dominating factor is Chromium’s headless rasterization speed, not the raw CPU of the system.
Atomic Persistence — Crash Resilience
Section titled “Atomic Persistence — Crash Resilience”The auto-save system uses asynchronous atomic writes implemented in the core of Ember:
1. Change detected → 500ms debounce2. Write to temporary file: project.json.tmp3. Only if write is successful: fs.rename(tmp → project.json)4. If process fails at any point: original project.json remains intactGuarantee: An unexpected shutdown, power failure, or system crash during auto-saving will never corrupt your project file. The .tmp file is automatically discarded on the next boot.
The 500ms debounce is implemented directly in the Zustand store, batching rapid inspector changes before each disk write to minimize IO operations.
Security Sandbox Overhead
Section titled “Security Sandbox Overhead”The plugin isolation system (Shadow DOM + fakeWindow Proxy) adds a critical layer of security with minimal performance impact:
| Component | Implementation | Impact on 60fps loop |
|---|---|---|
| Shadow DOM | attachShadow({ mode: 'open' }) | Negligible — native browser feature |
| fakeWindow Proxy | Intercepts access to the real window | < 0.1ms per frame |
| Polyfill getElementById | shadowRoot.querySelector('#id') | Equivalent to native |
| Total security overhead | — | < 0.5ms per frame |
The time window available for the 60fps preview loop is 16.6ms per frame. The sandbox overhead accounts for less than 3% of that budget.
Transparency Transformer — ProRes Alpha Channel
Section titled “Transparency Transformer — ProRes Alpha Channel”Exporting with a pure alpha channel requires a three-layer chain to guarantee real transparency when dropped into DaVinci Resolve, Premiere Pro, or After Effects:
| Layer | Implementation | Purpose |
|---|---|---|
| Chromium Flag | --transparent-background-color=0 | Forces a transparent background in the headless process |
| JS Injection | evaluatePage → body.style.backgroundColor = 'transparent' | Guarantees transparency before frame 0 is captured |
| Pixel Format | yuva444p10le (ProRes 4444, 10-bit) | Preserves the full alpha channel in the final .mov file |
The Frame 0 Fix resolves a critical bug where the first frame was captured before data hydration completed. The engine now leverages Remotion’s delayRender / continueRender to halt rendering until the plugin props are fully injected, guaranteeing the first exported frame is identical to the preview.
Data Probe Hydration — Windows CLI Limit Bypass
Section titled “Data Probe Hydration — Windows CLI Limit Bypass”Windows imposes a strict limit of ~32,767 characters on command-line arguments. Passing serialized JSON data (like base64 images or heavy code blocks) via CLI caused silent truncation and render failures.
Implemented Solution:
Main Process → boots ephemeral HTTP server on localhost:[PORT]RenderWrapper → fetch('http://localhost:[PORT]/props.json')Remotion → receives the full payload with no size limitServer → gracefully shuts down after render completesThis system bypasses the CLI character limit entirely and is completely transparent to the plugin developer.