mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-11-15 13:49:49 +00:00
fix(core): preserve per-element preload ordering in render mode
The lazy media preloading refactor split bindMediaMetadataListeners into two loops: bind all listeners first, then preload all elements. This changed when metadata listeners fire relative to .load(), shifting timeline duration hydration and causing 3 transition frames to render at a slightly different state in the style-9-prod regression test. Move eager preload back inside the per-element binding loop so listener attachment and .load() happen in the same iteration, matching the original ordering. Lazy-mode demotion stays in a separate block after mediaPreloader.refresh() since it needs the full clip list.
This commit is contained in:
@@ -1233,6 +1233,7 @@ export function initSandboxRuntimeModular(): void {
|
||||
const bindMediaMetadataListeners = () => {
|
||||
if (state.tornDown) return;
|
||||
const mediaEls = Array.from(document.querySelectorAll("video, audio")) as HTMLMediaElement[];
|
||||
const isLazy = mediaPreloader.isLazy();
|
||||
|
||||
let newElementsBound = false;
|
||||
for (const mediaEl of mediaEls) {
|
||||
@@ -1241,22 +1242,20 @@ export function initSandboxRuntimeModular(): void {
|
||||
newElementsBound = true;
|
||||
mediaEl.addEventListener("loadedmetadata", scheduleMetadataDurationHydration);
|
||||
mediaEl.addEventListener("durationchange", scheduleMetadataDurationHydration);
|
||||
|
||||
// In eager mode, preload inline (same ordering as before lazy preloading)
|
||||
if (!isLazy || isRenderMode) {
|
||||
if (mediaEl.preload !== "auto") mediaEl.preload = "auto";
|
||||
if (mediaEl.readyState < HTMLMediaElement.HAVE_FUTURE_DATA) mediaEl.load();
|
||||
}
|
||||
}
|
||||
|
||||
if (newElementsBound && !isRenderMode) {
|
||||
mediaPreloader.refresh();
|
||||
}
|
||||
|
||||
if (!mediaPreloader.isLazy() || isRenderMode) {
|
||||
for (const mediaEl of mediaEls) {
|
||||
if (mediaEl.preload !== "auto") {
|
||||
mediaEl.preload = "auto";
|
||||
}
|
||||
if (mediaEl.readyState < HTMLMediaElement.HAVE_FUTURE_DATA) {
|
||||
mediaEl.load();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Lazy-mode demotion runs separately after refresh updates the clip list
|
||||
if (mediaPreloader.isLazy() && !isRenderMode) {
|
||||
// Only demote timed media (elements with data-start) to metadata preload.
|
||||
// Untimed media (background audio, ambient loops, decorative video) must
|
||||
// keep their original preload state — the mediaPreloader only manages
|
||||
|
||||
Reference in New Issue
Block a user