Skip to content

[1/2] fix: keep a frame's embedded images when Safari draws an html5 clip - #279

Merged
dazzatronus merged 1 commit into
mainfrom
derk/html5-safari-embedded-images
Oct 30, 2026
Merged

dazzatronus merged 1 commit into
mainfrom
derk/html5-safari-embedded-images

Conversation

@dazzatronus

@dazzatronus dazzatronus commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

Safari drops large images from html5 frames. A clip's frames are drawn by loading the page as an SVG image, and WebKit lays that page out as offscreen. So a bitmap over about 500 KB once decoded (a 960×540 photo is about 2 MB) decodes asynchronously, and a draw that comes before the decode lands leaves it out. img.decode() doesn't wait for that decode and no event marks it. Redrawing the same SVG 400 ms apart showed the image appearing and disappearing, so any timed wait is a race.

In WebKit, each frame's SVG now starts with one hidden <img decoding="sync"> for each embedded base64 bitmap, which decodes it at full size within the draw. They're hidden with filter:opacity(0), because WebKit skips painting opacity:0 elements. The bake cache key gains a drawing version, so frames already cached without their images are redrawn.

WebKit is detected by navigator.vendor, which every iOS browser shares with Safari. Chrome doesn't need the extra decodes, and they cost it about 23% more bake time on the edit below.

Verify: npm run verify:ci. Then, in Safari, preview an html5 clip whose CSS has a large background-image data URI: every frame shows it. On one such edit (374 frames, full bake) the frames below 0.95 SSIM against a cloud render fell from 121 to 2. Chrome's export of that edit is identical to main's.

Risk: in WebKit each frame's SVG carries its embedded images twice (231 KB → 386 KB here), and the Safari bake took about 14% longer. If WebKit ever stops painting filter:opacity(0) elements, images go missing as they do today.

PR Adds Why separate
this PR #279 Embedded images decoded before Safari draws a frame; bake drawing version Safari-only cause, revertible alone
#280 Frames drawn on a software canvas; drawing version 2 Firefox-only cause; raises #279's version

Merge bottom-up: #280 targets #279's branch, and moves to main once #279 lands.

@dazzatronus
dazzatronus force-pushed the derk/html5-safari-embedded-images branch from baaecce to 36fc6f0 Compare October 30, 2026 12:36
@dazzatronus
dazzatronus merged commit 5154007 into main Oct 30, 2026
1 check passed
github-actions Bot pushed a commit that referenced this pull request Oct 30, 2026
## [2.30.1](v2.30.0...v2.30.1) (2026-10-30)

### Bug Fixes

* draw clip filters in the preview as the render applies them ([#265](#265)) ([ac02f9b](ac02f9b))
* draw html5 frames on a software canvas so Firefox keeps their gradients ([#280](#280)) ([d508db8](d508db8))
* **export:** draw export frames into one stencil target so Firefox keeps masked content ([#278](#278)) ([f431c6b](f431c6b))
* **export:** tag browser exports as limited range so Safari's whites stay white ([#277](#277)) ([c6150eb](c6150eb))
* keep a frame's embedded images when Safari draws an html5 clip ([#279](#279)) ([5154007](5154007))
* keep baking html5 clips while their tab is in the background ([#281](#281)) ([e1fa158](e1fa158))
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 2.30.1 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant