« All posts

How a Browser Video Renderer's Frame Time Was Cut by 80%

How four hidden bottlenecks in a browser video renderer were found and fixed, cutting frame time 80% and exposing a subtle opacity bug.

An engineering team investigated why their browser-based video renderer — which draws DOM layers onto canvas and encodes frames via WebCodecs — was producing roughly one frame per second. Instead of profiling the whole pipeline, they timed each stage separately (DOM capture, effect compositing, overlay processing, encoding) and isolated four distinct bottlenecks.

The culprits included preview-only overlay logic running unnecessarily during export, WebGL contexts being torn down and rebuilt every time an effect layer's bounding box changed, and — the biggest offender — a capture cache whose key included draw-time properties like opacity and transform. That meant a simple fade animation forced a full DOM rasterization (domToCanvas) on every single frame. Splitting the cache into a content-only layer and a full-props layer let fades and slides redraw from a cached bitmap in 1-3ms instead of re-rasterizing.

A pixel-diff verification pass, run to confirm the optimization didn't change output, also surfaced a real correctness bug: export was applying opacity twice (baked into the bitmap and again at draw time), making every exported fade slightly more opaque than the preview. After the fixes, scene medians dropped from 0.5-1.0s to 90-165ms per frame, and a 30-second render fell from 10 minutes to 3 on the server. The writeup is a solid case study in per-stage measurement, separating content from transform, and using pixel diffs to catch regressions and hidden bugs alike.

This synthesis was produced from its source by AI; there is no human editor or manual review step. How we work