Skip to content

Commit b13fb50

Browse files
committed
wip: journal per chain of rerenders
1 parent 89a07ff commit b13fb50

File tree

2 files changed

+31
-17
lines changed

2 files changed

+31
-17
lines changed

packages/qwik/src/core/client/vnode-diff.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ import { serializeAttribute } from '../shared/utils/styles';
5151
import { isArray, type ValueOrPromise } from '../shared/utils/types';
5252
import { trackSignalAndAssignHost } from '../use/use-core';
5353
import { TaskFlags, cleanupTask, isTask } from '../use/use-task';
54-
import type { DomContainer } from './dom-container';
5554
import { VNodeFlags, type ClientAttrs, type ClientContainer } from './types';
5655
import { mapApp_findIndx, mapArray_set } from './util-mapArray';
5756
import {
@@ -82,14 +81,16 @@ import {
8281
import type { ElementVNode, TextVNode, VNode, VirtualVNode } from './vnode-impl';
8382
import { getAttributeNamespace, getNewElementNamespaceData } from './vnode-namespace';
8483

84+
export type VNodeJournalRef = { $journal$: VNodeJournal; $refCount$: number };
85+
8586
export const vnode_diff = (
8687
container: ClientContainer,
8788
jsxNode: JSXChildren,
8889
vStartNode: VNode,
89-
scopedStyleIdPrefix: string | null
90+
scopedStyleIdPrefix: string | null,
91+
journalRef: VNodeJournalRef = { $journal$: [], $refCount$: 1 }
9092
) => {
91-
let journal = (container as DomContainer).$journal$;
92-
93+
let journal = journalRef.$journal$;
9394
/**
9495
* Stack is used to keep track of the state of the traversal.
9596
*
@@ -231,6 +232,7 @@ export const vnode_diff = (
231232
}
232233
} else if (jsxValue === (SkipRender as JSXChildren)) {
233234
// do nothing, we are skipping this node
235+
// Note, this probably breaks async stuff
234236
journal = [];
235237
} else {
236238
expectText('');
@@ -559,6 +561,11 @@ export const vnode_diff = (
559561
diff(jsxNode, vHostNode);
560562
}
561563
}
564+
journalRef.$refCount$--;
565+
if (journalRef.$refCount$ === 0) {
566+
// all done with the journal, pass it to the container
567+
container.$journal$.push(...journalRef.$journal$);
568+
}
562569
}
563570

564571
function expectNoChildren() {
@@ -1268,7 +1275,8 @@ export const vnode_diff = (
12681275
* deleted.
12691276
*/
12701277
(host as VirtualVNode).flags &= ~VNodeFlags.Deleted;
1271-
container.$scheduler$(ChoreType.COMPONENT, host, componentQRL, vNodeProps);
1278+
journalRef.$refCount$++;
1279+
container.$scheduler$(ChoreType.COMPONENT, host, componentQRL, vNodeProps, journalRef);
12721280
}
12731281
}
12741282
descendContentToProject(jsxNode.children, host);

packages/qwik/src/core/shared/scheduler.ts

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -80,13 +80,17 @@
8080
* declaration order within component.
8181
*/
8282

83+
import { ChoreArray, choreComparator } from '../client/chore-array';
8384
import { type DomContainer } from '../client/dom-container';
8485
import { VNodeFlags, type ClientContainer } from '../client/types';
8586
import { VNodeJournalOpCode, vnode_isVNode } from '../client/vnode';
86-
import { vnode_diff } from '../client/vnode-diff';
87+
import { vnode_diff, type VNodeJournalRef } from '../client/vnode-diff';
88+
import type { ElementVNode, VirtualVNode } from '../client/vnode-impl';
89+
import { AsyncComputedSignalImpl } from '../reactive-primitives/impl/async-computed-signal-impl';
8790
import { ComputedSignalImpl } from '../reactive-primitives/impl/computed-signal-impl';
8891
import { WrappedSignalImpl } from '../reactive-primitives/impl/wrapped-signal-impl';
8992
import { isSignal, type Signal } from '../reactive-primitives/signal.public';
93+
import { isSsrNode } from '../reactive-primitives/subscriber';
9094
import type { NodePropPayload } from '../reactive-primitives/subscription-data';
9195
import {
9296
SignalFlags,
@@ -97,6 +101,7 @@ import {
97101
} from '../reactive-primitives/types';
98102
import { scheduleEffects } from '../reactive-primitives/utils';
99103
import { type ISsrNode, type SSRContainer } from '../ssr/ssr-types';
104+
import { invoke, newInvokeContext } from '../use/use-core';
100105
import { runResource, type ResourceDescriptor } from '../use/use-resource';
101106
import {
102107
Task,
@@ -110,23 +115,18 @@ import { executeComponent } from './component-execution';
110115
import type { OnRenderFn } from './component.public';
111116
import type { Props } from './jsx/jsx-runtime';
112117
import type { JSXOutput } from './jsx/types/jsx-node';
118+
import { createNextTick } from './platform/next-tick';
113119
import { isServerPlatform } from './platform/platform';
114120
import { type QRLInternal } from './qrl/qrl-class';
121+
import { findBlockingChore, findBlockingChoreForVisible } from './scheduler-rules';
115122
import { SsrNodeFlags, type Container, type HostElement } from './types';
116123
import { ChoreType } from './util-chore-type';
124+
import { logWarn } from './utils/log';
117125
import { QScopedStyle } from './utils/markers';
118126
import { isPromise, maybeThen, retryOnPromise, safeCall } from './utils/promises';
119127
import { addComponentStylePrefix } from './utils/scoped-styles';
120128
import { serializeAttribute } from './utils/styles';
121129
import { type ValueOrPromise } from './utils/types';
122-
import { invoke, newInvokeContext } from '../use/use-core';
123-
import { findBlockingChore, findBlockingChoreForVisible } from './scheduler-rules';
124-
import { createNextTick } from './platform/next-tick';
125-
import { AsyncComputedSignalImpl } from '../reactive-primitives/impl/async-computed-signal-impl';
126-
import { isSsrNode } from '../reactive-primitives/subscriber';
127-
import { logWarn } from './utils/log';
128-
import type { ElementVNode, VirtualVNode } from '../client/vnode-impl';
129-
import { ChoreArray, choreComparator } from '../client/chore-array';
130130

131131
// Turn this on to get debug output of what the scheduler is doing.
132132
const DEBUG: boolean = false;
@@ -243,7 +243,8 @@ export const createScheduler = (
243243
type: ChoreType.COMPONENT,
244244
host: HostElement,
245245
qrl: QRLInternal<OnRenderFn<unknown>>,
246-
props: Props | null
246+
props: Props | null,
247+
journalRef?: VNodeJournalRef
247248
): Chore<ChoreType.COMPONENT>;
248249
function schedule(
249250
type: ChoreType.NODE_DIFF,
@@ -263,7 +264,8 @@ export const createScheduler = (
263264
type: T,
264265
hostOrTask: HostElement | Task | null = null,
265266
targetOrQrl: ChoreTarget | string | null = null,
266-
payload: any = null
267+
payload: unknown = null,
268+
extra?: unknown
267269
): Chore<T> | null {
268270
if (type === ChoreType.WAIT_FOR_QUEUE && drainChore) {
269271
return drainChore as Chore<T>;
@@ -293,6 +295,9 @@ export const createScheduler = (
293295
$reject$: undefined,
294296
$returnValue$: null!,
295297
};
298+
if (extra !== undefined) {
299+
(chore as any).$extra$ = extra;
300+
}
296301

297302
if (type === ChoreType.WAIT_FOR_QUEUE) {
298303
getChorePromise(chore);
@@ -659,7 +664,8 @@ This is often caused by modifying a signal in an already rendered component duri
659664
container as ClientContainer,
660665
jsx,
661666
host as VirtualVNode,
662-
addComponentStylePrefix(styleScopedId)
667+
addComponentStylePrefix(styleScopedId),
668+
(chore as any).$extra$
663669
)
664670
);
665671
}

0 commit comments

Comments
 (0)