mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-10-30 09:16:55 +00:00
perf(studio): a settled timeline's composition check scans only its hosts, not the whole preview (#5880)
This commit is contained in:
@@ -118,6 +118,47 @@ describe("buildMissingCompositionElements — hfId (R7)", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("buildMissingCompositionElements — on a settled timeline", () => {
|
||||
// Studio runs this on every runtime state tick, so a timeline with nothing to add must cost one host scan.
|
||||
const settled = () =>
|
||||
makeDoc(`
|
||||
<div data-composition-id="root">
|
||||
<div id="intro" data-composition-id="intro" data-start="0" data-duration="3"></div>
|
||||
${Array.from({ length: 40 }, (_, i) => `<video id="clip-${i}" data-start="${i}" data-duration="1"></video>`).join("")}
|
||||
</div>
|
||||
`);
|
||||
const rows = ["intro", ...Array.from({ length: 40 }, (_, i) => `clip-${i}`)].map((id, i) => ({
|
||||
id,
|
||||
key: id,
|
||||
tag: id === "intro" ? "div" : "video",
|
||||
start: i,
|
||||
duration: 1,
|
||||
track: 0,
|
||||
}));
|
||||
|
||||
it("walks no more of the document than the hosts when nothing is missing or patchable", () => {
|
||||
const doc = settled();
|
||||
const scans = vi.spyOn(doc, "querySelectorAll");
|
||||
const result = buildMissingCompositionElements(doc, window as IframeWindow, rows, 40);
|
||||
expect(scans.mock.calls.map(([selector]) => selector)).toEqual([
|
||||
"[data-composition-id][data-start]",
|
||||
]);
|
||||
expect([result.missing, result.patched, result.updatedEls]).toEqual([[], false, rows]);
|
||||
});
|
||||
|
||||
it("still patches a row whose host carries its source", () => {
|
||||
const doc = settled();
|
||||
doc.getElementById("intro")!.setAttribute("data-composition-src", "compositions/intro.html");
|
||||
const { patched, updatedEls } = buildMissingCompositionElements(
|
||||
doc,
|
||||
window as IframeWindow,
|
||||
rows,
|
||||
40,
|
||||
);
|
||||
expect([patched, updatedEls[0]?.compositionSrc]).toEqual([true, "compositions/intro.html"]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("buildMissingCompositionElements — nested master time", () => {
|
||||
it("places hosts two and three levels deep at their master time", () => {
|
||||
const doc = makeDoc(`
|
||||
|
||||
@@ -493,7 +493,7 @@ export function buildMissingCompositionElements(
|
||||
const hosts = doc.querySelectorAll("[data-composition-id][data-start]");
|
||||
const missing: TimelineElement[] = [];
|
||||
|
||||
const resolveEnd = createReferenceEndResolver(createTimedElementLookup(doc), iframeWin);
|
||||
let resolveEnd: ReturnType<typeof createReferenceEndResolver> | undefined;
|
||||
const masterTime = createRuntimeStartTimeResolver({
|
||||
timelineRegistry: iframeWin.__timelines,
|
||||
includeAuthoredTimingAttrs: true,
|
||||
@@ -505,6 +505,7 @@ export function buildMissingCompositionElements(
|
||||
const compId = el.getAttribute("data-composition-id");
|
||||
if (!compId || compId === rootCompId) continue;
|
||||
if (existingIds.has(el.id) || existingIds.has(compId)) continue;
|
||||
resolveEnd ??= createReferenceEndResolver(createTimedElementLookup(doc), iframeWin);
|
||||
const entry = buildMissingCompositionEntry({
|
||||
doc,
|
||||
iframeWin,
|
||||
@@ -518,7 +519,9 @@ export function buildMissingCompositionElements(
|
||||
if (entry) missing.push(entry);
|
||||
}
|
||||
|
||||
// Patch existing elements that are missing compositionSrc
|
||||
// Patch existing elements that are missing compositionSrc; only a host carrying its source can supply one.
|
||||
if (!doc.querySelector("[data-composition-src], [data-composition-file]"))
|
||||
return { missing, updatedEls: currentEls as TimelineElement[], patched: false };
|
||||
let patched = false;
|
||||
const findHost = previewElementFinder(doc);
|
||||
const updatedEls = (currentEls as TimelineElement[]).map((existing) => {
|
||||
|
||||
Reference in New Issue
Block a user