Skip to content

perf(producer): revert webp extraction default (20x slower than jpg on this host)#441

Closed
jrusso1020 wants to merge 1 commit intoperf/producer-stack-cleanupfrom
perf/producer-revert-webp-default
Closed

perf(producer): revert webp extraction default (20x slower than jpg on this host)#441
jrusso1020 wants to merge 1 commit intoperf/producer-stack-cleanupfrom
perf/producer-revert-webp-default

Conversation

@jrusso1020
Copy link
Copy Markdown
Collaborator

@jrusso1020 jrusso1020 commented Apr 23, 2026

What

Reverts renderOrchestrator.ts's explicit format: "webp" on the producer's single extractAllVideoFrames call. The extractor now falls back to its default ("jpg").

Keeps everything else from PR #434 intact: ExtractionOptions.format still accepts "webp", the injector's mimeTypeForFramePath still routes .webpimage/webp, and the cache schema bump (v1→v2) stays.

Why

Caught by running the architecture review's validation plan (hyperframes-notes/producer-render-architecture-review-2026-04-21.md § Validation plan) against real fixtures after /simplify.

Numbers on vfr-screen-recording (3s @ 30fps, 480×332, 90 frames):

Config videoExtractMs totalElapsedMs
origin/main (baseline, jpg) 211ms 2632ms
Stack tip with format: "webp" 1365ms 3847ms (+46%)
Stack tip with format: "jpg" 247ms 2695ms

Direct ffmpeg comparison on the same clip isolates libwebp as the culprit:

Encoder 90 frames elapsed
-q:v 2 (jpg, libjpeg-turbo) 0.06s
-c:v libwebp -quality 95 -lossless 0 1.18s (≈ 20× slower)
-c:v libwebp -quality 80 -lossless 0 0.98s (≈ 16× slower)

libwebp runs multi-pass analysis to minimize bits; libjpeg-turbo is single-pass SIMD-optimized. For synthetic/gradient content (testsrc, screen recordings, UI-heavy comps), the per-byte compression win is marginal (32KB webp vs 33KB jpg in my measurement) but the encode cost is enormous.

The architecture review's WebP suggestion was premised on "collapsing an if (hasAlpha) branch in extraction and injection." This codebase's extractor already defaults to JPG with no alpha branch in the producer's call site — so the unification benefit is theoretical, and the encode cost is real.

How

Single-line change: drop format: "webp" from the producer's extract options. Adds an explanatory comment pointing at the validation-plan finding.

All other PR #434 infrastructure stays: "webp" remains a valid ExtractionOptions.format value, the extractor's libwebp branch works, the injector correctly tags webp data URIs, the cache schema is still v2 (preventing cross-contamination with any legacy v1 jpg entries).

Test plan

  • Full engine suite still passes (373 tests — no test changes, behavior-only).
  • Typecheck clean.
  • Lint + format clean.
  • Post-revert validation on vfr-screen-recording: videoExtractMs: 247ms (down from 1365ms, back within ~17% of origin/main's 211ms — remaining delta is instrumentation overhead plus the segment-scoped VFR preflight).

Stack

Tip of the perf stack: #430#432#433#434#435#437#441.

Follow-ups

  • Re-evaluate WebP when a faster encoder is available (hardware encode, AVIF, or a lossless-webp preset that skips the multi-pass). WebP could then land as default without the 20× cost.
  • If a future alpha-input path needs cross-frame alpha, the producer can opt in with format: "webp" per-composition.

@jrusso1020
Copy link
Copy Markdown
Collaborator Author

Closed: only existed to revert #434; both drop from the rebuilt stack. See hyperframes-notes/perf-stack-rebuild-plan-2026-04-23.md

@jrusso1020 jrusso1020 closed this Apr 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant