Skip to content

Commit 6d9085c

Browse files
committed
lazy-define: resume large scans via scheduler.postTask when available
Continue an interrupted scan with scheduler.postTask (default user-visible priority), which yields to input but resumes sooner than the next animation frame, so large-DOM scans finish faster without blocking. Falls back to requestAnimationFrame where postTask is unavailable.
1 parent eea8b4b commit 6d9085c

1 file changed

Lines changed: 18 additions & 3 deletions

File tree

src/lazy-define.ts

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,29 @@ const SCAN_BUDGET_MS = 4
7373
// keeps that overhead negligible while still yielding promptly.
7474
const SCAN_CHECK_INTERVAL = 1024
7575

76+
type PostTaskScheduler = {postTask(callback: () => void): Promise<unknown>}
77+
const nativeScheduler = (globalThis as unknown as {scheduler?: PostTaskScheduler}).scheduler
78+
7679
function scan(element: ElementLike) {
7780
scanQueue.push(element)
7881
if (scanScheduled) return
7982
scanScheduled = true
8083
requestAnimationFrame(runScan)
8184
}
8285

86+
// Resume an interrupted scan. Prefer `scheduler.postTask` (default 'user-visible'
87+
// priority) so a large scan continues promptly after yielding to input rather
88+
// than waiting a whole frame; fall back to requestAnimationFrame.
89+
function scheduleScanContinuation() {
90+
scanScheduled = true
91+
if (nativeScheduler?.postTask) {
92+
// eslint-disable-next-line github/no-then
93+
nativeScheduler.postTask(runScan).catch(() => undefined)
94+
} else {
95+
requestAnimationFrame(runScan)
96+
}
97+
}
98+
8399
function resolveTag(tagName: string, el: Element | null): void {
84100
const callbacks = dynamicElements.get(tagName)
85101
if (!callbacks) return
@@ -142,9 +158,8 @@ function runScan(): void {
142158
if (++sinceCheck >= SCAN_CHECK_INTERVAL) {
143159
sinceCheck = 0
144160
if (performance.now() >= deadline) {
145-
// Out of budget — resume this same walker on the next frame.
146-
scanScheduled = true
147-
requestAnimationFrame(runScan)
161+
// Out of budget — resume this same walker after yielding.
162+
scheduleScanContinuation()
148163
return
149164
}
150165
}

0 commit comments

Comments
 (0)