@@ -33,7 +33,7 @@ import type { ValueOrPromise } from '../utils/types';
3333import { assertDefined , assertFalse } from '../error/assert' ;
3434import type { Container } from '../types' ;
3535import { VNodeFlags } from '../../client/types' ;
36- import { isBrowser , isDev , isServer } from '@qwik.dev/core/build' ;
36+ import { isDev , isServer } from '@qwik.dev/core/build' ;
3737
3838const DEBUG = false ;
3939
@@ -56,27 +56,24 @@ function scheduleYield(): void {
5656 }
5757}
5858
59- /** Options for walking a cursor. */
60- export interface WalkOptions {
61- /** Time budget in milliseconds (for DOM time-slicing). If exceeded, walk pauses. */
62- timeBudget : number ;
63- }
64-
6559/**
6660 * Processes the cursor queue, walking each cursor in turn.
6761 *
6862 * @param options - Walk options (time budget, etc.)
6963 */
70- export function processCursorQueue (
71- options : WalkOptions = {
72- timeBudget : 1000 / 60 , // 60fps
73- }
74- ) : void {
64+ export function processCursorQueue ( ) : void {
7565 isNextTickScheduled = false ;
66+ const startTime = performance . now ( ) ;
67+ const yieldTime = startTime + 15 ; // 16 ms = 60 FPS, use 15 to yield slightly before next frame
7668
7769 let cursor : Cursor | null = null ;
7870 while ( ( cursor = getHighestPriorityCursor ( ) ) ) {
79- walkCursor ( cursor , options ) ;
71+ if ( walkCursor ( cursor , yieldTime ) ) {
72+ // Cursor overran time budget, yield to browser
73+ // Note that each tick we process at least one thing
74+ scheduleYield ( ) ;
75+ return ;
76+ }
8077 }
8178}
8279
@@ -96,13 +93,12 @@ export function processCursorQueue(
9693 * Note that there is only one walker for all containers in the app with the same Qwik version.
9794 *
9895 * @param cursor - The cursor to walk
99- * @param options - Walk options (time budget, etc.)
100- * @returns Walk result indicating completion status
96+ * @param until - Time budget (timestamp to yield by)
97+ * @returns `true` if the walk was paused due to time budget (do not process more cursors in this
98+ * tick)
10199 */
102- export function walkCursor ( cursor : Cursor , options : WalkOptions ) : void {
103- const { timeBudget } = options ;
100+ export function walkCursor ( cursor : Cursor , until : number ) : boolean | void {
104101 const isRunningOnServer = import . meta. env . TEST ? isServerPlatform ( ) : isServer ;
105- const startTime = performance . now ( ) ;
106102
107103 const cursorData = getCursorData ( cursor ) ! ;
108104
@@ -213,13 +209,8 @@ export function walkCursor(cursor: Cursor, options: WalkOptions): void {
213209 }
214210
215211 // Check time budget (only for DOM, not SSR)
216- if ( isBrowser ) {
217- const elapsed = performance . now ( ) - startTime ;
218- if ( elapsed >= timeBudget ) {
219- // Schedule continuation as macrotask to actually yield to browser
220- scheduleYield ( ) ;
221- return ;
222- }
212+ if ( performance . now ( ) >= until ) {
213+ return true ;
223214 }
224215 }
225216 isDev &&
0 commit comments