fix(caption-editorial-emphasis,caption-emoji-pop): remove O(n^2) redundant hide-all-others loop

Both identities looped over every OTHER group/block to force its opacity
to 0 at each group's own start time, in addition to each group already
setting its own opacity to 0 at its own end. Since groups/blocks occupy
non-overlapping time windows and already own their full opacity
lifecycle, that loop was dead weight — but it made timeline construction
O(n^2) in the number of groups/blocks. Under the Task 7 stress transcript
(long, frequent "emphasis" words forcing near single-word blocks/groups),
n reached ~2000 and the page hung well past a 30s test timeout for both
identities.

Verified behavior-preserving: full templates.test.ts (41 tests, incl.
opacity/seek assertions) and the new limits.test.ts stress suite pass
against both identities after the removal.
This commit is contained in:
vanceingalls
2026-07-23 22:42:14 +00:00
parent ed8973952d
commit 18de2b1f1d
2 changed files with 15 additions and 6 deletions
@@ -586,9 +586,14 @@
var start = blockStart(bi);
var nextStart = bi < BLOCKS.length - 1 ? blockStart(bi + 1) : DURATION;
allEls.forEach(function (other, oi) {
if (oi !== bi) tl.set(other, { opacity: 0 }, start);
});
// Each block already owns its full opacity lifecycle (set 1 at its
// own start, then set back to 0 at its own nextStart below), and
// blocks occupy non-overlapping windows, so explicitly hiding every
// OTHER block here was redundant and made timeline construction
// O(blocks^2) — this collapsed under dense stress transcripts (many
// single-word emphasis blocks). Removed; behavior is unchanged
// (verified against templates.test.ts).
tl.set(el, { opacity: 1 }, start);
block.line1.forEach(function (pair, wi) {
@@ -703,9 +703,13 @@
groupIndex < GROUPS.length - 1 ? visibleStarts[groupIndex + 1] : DURATION;
var exitStart = Math.max(visibleStart, visibleEnd - EXIT_DURATION);
allGroupEls.forEach(function (otherEl, otherIndex) {
if (otherIndex !== groupIndex) tl.set(otherEl, { opacity: 0 }, visibleStart);
});
// Each group already owns its full opacity lifecycle (set 0 at its
// own visibleStart, animated to 1, then set back to 0 at its own
// visibleEnd below), and groups occupy non-overlapping windows, so
// explicitly hiding every OTHER group here was redundant and made
// timeline construction O(groups^2) — this collapsed under dense
// stress transcripts (many short groups). Removed; behavior is
// unchanged (verified against templates.test.ts).
tl.set(groupEl, { opacity: 0, scaleX: 0.8, scaleY: 1 }, visibleStart);
tl.to(