Skip to content

Commit ea16016

Browse files
wmertensVarixo
andcommitted
wip cursors scheduling
- add cursor management - remove chore based scheduler - refactor VNode - remove journal Co-authored-by: Varixo <[email protected]>
1 parent ce46152 commit ea16016

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+1930
-842
lines changed

packages/qwik/src/core/client/dom-container.ts

Lines changed: 43 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import {
2727
QScopedStyle,
2828
QStyle,
2929
QStyleSelector,
30+
QStylesAllSelector,
3031
Q_PROPS_SEPARATOR,
3132
USE_ON_LOCAL_SEQ_IDX,
3233
getQFuncs,
@@ -48,22 +49,21 @@ import {
4849
import { mapArray_get, mapArray_has, mapArray_set } from './util-mapArray';
4950
import {
5051
VNodeJournalOpCode,
51-
vnode_applyJournal,
5252
vnode_createErrorDiv,
53-
vnode_getDomParent,
54-
vnode_getProps,
53+
vnode_getProp,
5554
vnode_insertBefore,
5655
vnode_isElementVNode,
57-
vnode_isVNode,
5856
vnode_isVirtualVNode,
5957
vnode_locate,
6058
vnode_newUnMaterializedElement,
61-
type VNodeJournal,
59+
vnode_setProp,
6260
} from './vnode';
63-
import type { ElementVNode, VNode, VirtualVNode } from './vnode-impl';
61+
import type { ElementVNode } from '../shared/vnode/element-vnode';
62+
import type { VNode } from '../shared/vnode/vnode';
63+
import type { VirtualVNode } from '../shared/vnode/virtual-vnode';
6464

6565
/** @public */
66-
export function getDomContainer(element: Element | VNode): IClientContainer {
66+
export function getDomContainer(element: Element): IClientContainer {
6767
const qContainerElement = _getQContainerElement(element);
6868
if (!qContainerElement) {
6969
throw qError(QError.containerNotFound);
@@ -96,7 +96,6 @@ export class DomContainer extends _SharedContainer implements IClientContainer {
9696
public qManifestHash: string;
9797
public rootVNode: ElementVNode;
9898
public document: QDocument;
99-
public $journal$: VNodeJournal;
10099
public $rawStateData$: unknown[];
101100
public $storeProxyMap$: ObjToProxyMap = new WeakMap();
102101
public $qFuncs$: Array<(...args: unknown[]) => unknown>;
@@ -108,29 +107,14 @@ export class DomContainer extends _SharedContainer implements IClientContainer {
108107
private $styleIds$: Set<string> | null = null;
109108

110109
constructor(element: ContainerElement) {
111-
super(
112-
() => {
113-
this.$flushEpoch$++;
114-
vnode_applyJournal(this.$journal$);
115-
},
116-
{},
117-
element.getAttribute(QLocaleAttr)!
118-
);
110+
super({}, element.getAttribute(QLocaleAttr)!);
119111
this.qContainer = element.getAttribute(QContainerAttr)!;
120112
if (!this.qContainer) {
121113
throw qError(QError.elementWithoutContainer);
122114
}
123-
this.$journal$ = [
124-
// The first time we render we need to hoist the styles.
125-
// (Meaning we need to move all styles from component inline to <head>)
126-
// We bulk move all of the styles, because the expensive part is
127-
// for the browser to recompute the styles, (not the actual DOM manipulation.)
128-
// By moving all of them at once we can minimize the reflow.
129-
VNodeJournalOpCode.HoistStyles,
130-
element.ownerDocument,
131-
];
132115
this.document = element.ownerDocument as QDocument;
133116
this.element = element;
117+
this.$hoistStyles$();
134118
this.$buildBase$ = element.getAttribute(QBaseAttr)!;
135119
this.$instanceHash$ = element.getAttribute(QInstanceAttr)!;
136120
this.qManifestHash = element.getAttribute(QManifestHashAttr)!;
@@ -157,7 +141,24 @@ export class DomContainer extends _SharedContainer implements IClientContainer {
157141
}
158142
}
159143

160-
$setRawState$(id: number, vParent: ElementVNode | VirtualVNode): void {
144+
/**
145+
* The first time we render we need to hoist the styles. (Meaning we need to move all styles from
146+
* component inline to <head>)
147+
*
148+
* We bulk move all of the styles, because the expensive part is for the browser to recompute the
149+
* styles, (not the actual DOM manipulation.) By moving all of them at once we can minimize the
150+
* reflow.
151+
*/
152+
$hoistStyles$(): void {
153+
const document = this.element.ownerDocument;
154+
const head = document.head;
155+
const styles = document.querySelectorAll(QStylesAllSelector);
156+
for (let i = 0; i < styles.length; i++) {
157+
head.appendChild(styles[i]);
158+
}
159+
}
160+
161+
$setRawState$(id: number, vParent: VNode): void {
161162
this.$stateData$[id] = vParent;
162163
}
163164

@@ -168,17 +169,15 @@ export class DomContainer extends _SharedContainer implements IClientContainer {
168169
handleError(err: any, host: VNode | null): void {
169170
if (qDev && host) {
170171
if (typeof document !== 'undefined') {
171-
const vHost = host as VirtualVNode;
172-
const journal: VNodeJournal = [];
172+
const vHost = host;
173173
const vHostParent = vHost.parent;
174174
const vHostNextSibling = vHost.nextSibling as VNode | null;
175-
const vErrorDiv = vnode_createErrorDiv(document, vHost, err, journal);
175+
const vErrorDiv = vnode_createErrorDiv(document, vHost, err);
176176
// If the host is an element node, we need to insert the error div into its parent.
177177
const insertHost = vnode_isElementVNode(vHost) ? vHostParent || vHost : vHost;
178178
// If the host is different then we need to insert errored-host in the same position as the host.
179179
const insertBefore = insertHost === vHost ? null : vHostNextSibling;
180-
vnode_insertBefore(journal, insertHost, vErrorDiv, insertBefore);
181-
vnode_applyJournal(journal);
180+
vnode_insertBefore(insertHost as ElementVNode | VirtualVNode, vErrorDiv, insertBefore);
182181
}
183182

184183
if (err && err instanceof Error) {
@@ -220,7 +219,7 @@ export class DomContainer extends _SharedContainer implements IClientContainer {
220219
let vNode: VNode | null = host.parent;
221220
while (vNode) {
222221
if (vnode_isVirtualVNode(vNode)) {
223-
if (vNode.getProp(OnRenderProp, null) !== null) {
222+
if (vnode_getProp(vNode, OnRenderProp, null) !== null) {
224223
return vNode;
225224
}
226225
vNode =
@@ -236,7 +235,7 @@ export class DomContainer extends _SharedContainer implements IClientContainer {
236235

237236
setHostProp<T>(host: HostElement, name: string, value: T): void {
238237
const vNode: VirtualVNode = host as any;
239-
vNode.setProp(name, value);
238+
vnode_setProp(vNode, name, value);
240239
}
241240

242241
getHostProp<T>(host: HostElement, name: string): T | null {
@@ -255,20 +254,21 @@ export class DomContainer extends _SharedContainer implements IClientContainer {
255254
getObjectById = parseInt;
256255
break;
257256
}
258-
return vNode.getProp(name, getObjectById);
257+
return vnode_getProp(vNode, name, getObjectById);
259258
}
260259

261260
ensureProjectionResolved(vNode: VirtualVNode): void {
262261
if ((vNode.flags & VNodeFlags.Resolved) === 0) {
263262
vNode.flags |= VNodeFlags.Resolved;
264-
const props = vnode_getProps(vNode);
265-
for (let i = 0; i < props.length; i = i + 2) {
266-
const prop = props[i] as string;
267-
if (isSlotProp(prop)) {
268-
const value = props[i + 1];
269-
if (typeof value == 'string') {
270-
const projection = this.vNodeLocate(value);
271-
props[i + 1] = projection;
263+
const props = vNode.props;
264+
if (props) {
265+
for (const prop of Object.keys(props)) {
266+
if (isSlotProp(prop)) {
267+
const value = prop;
268+
if (typeof value == 'string') {
269+
const projection = this.vNodeLocate(value);
270+
props[prop] = projection;
271+
}
272272
}
273273
}
274274
}
@@ -304,7 +304,7 @@ export class DomContainer extends _SharedContainer implements IClientContainer {
304304
const styleElement = this.document.createElement('style');
305305
styleElement.setAttribute(QStyle, styleId);
306306
styleElement.textContent = content;
307-
this.$journal$.push(VNodeJournalOpCode.Insert, this.document.head, null, styleElement);
307+
this.document.head.appendChild(styleElement);
308308
}
309309
}
310310

packages/qwik/src/core/client/dom-render.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1-
import type { FunctionComponent, JSXNode, JSXOutput } from '../shared/jsx/types/jsx-node';
1+
import type { FunctionComponent, JSXOutput } from '../shared/jsx/types/jsx-node';
22
import { isDocument, isElement } from '../shared/utils/element';
3-
import { ChoreType } from '../shared/util-chore-type';
43
import { QContainerValue } from '../shared/types';
54
import { DomContainer, getDomContainer } from './dom-container';
65
import { cleanup } from './vnode-diff';
7-
import { QContainerAttr } from '../shared/utils/markers';
6+
import { NODE_DIFF_DATA_KEY, QContainerAttr } from '../shared/utils/markers';
87
import type { RenderOptions, RenderResult } from './types';
98
import { qDev } from '../shared/utils/qdev';
109
import { QError, qError } from '../shared/error/error';
10+
import { vnode_setProp } from './vnode';
11+
import { markVNodeDirty } from '../shared/vnode/vnode-dirty';
12+
import { ChoreBits } from '../shared/vnode/enums/chore-bits.enum';
1113

1214
/**
1315
* Render JSX.
@@ -42,8 +44,9 @@ export const render = async (
4244
const container = getDomContainer(parent as HTMLElement) as DomContainer;
4345
container.$serverData$ = opts.serverData || {};
4446
const host = container.rootVNode;
45-
container.$scheduler$(ChoreType.NODE_DIFF, host, host, jsxNode as JSXNode);
46-
await container.$scheduler$(ChoreType.WAIT_FOR_QUEUE).$returnValue$;
47+
vnode_setProp(host, NODE_DIFF_DATA_KEY, jsxNode);
48+
markVNodeDirty(container, host, ChoreBits.NODE_DIFF);
49+
await container.$renderPromise$;
4750
return {
4851
cleanup: () => {
4952
cleanup(container, container.rootVNode);

packages/qwik/src/core/client/types.ts

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
import type { QRL } from '../shared/qrl/qrl.public';
44
import type { Container } from '../shared/types';
5-
import type { VNodeJournal } from './vnode';
6-
import type { ElementVNode, VirtualVNode } from './vnode-impl';
5+
import type { ElementVNode } from '../shared/vnode/element-vnode';
6+
import type { VirtualVNode } from '../shared/vnode/virtual-vnode';
77

88
export type ClientAttrKey = string;
99
export type ClientAttrValue = string | null;
@@ -17,9 +17,7 @@ export interface ClientContainer extends Container {
1717
$locale$: string;
1818
qManifestHash: string;
1919
rootVNode: ElementVNode;
20-
$journal$: VNodeJournal;
2120
$forwardRefs$: Array<number> | null;
22-
$flushEpoch$: number;
2321
parseQRL<T = unknown>(qrl: string): QRL<T>;
2422
$setRawState$(id: number, vParent: ElementVNode | VirtualVNode): void;
2523
}
@@ -74,30 +72,32 @@ export interface QDocument extends Document {
7472
* @internal
7573
*/
7674
export const enum VNodeFlags {
77-
Element /* ****************** */ = 0b00_000001,
78-
Virtual /* ****************** */ = 0b00_000010,
79-
ELEMENT_OR_VIRTUAL_MASK /* ** */ = 0b00_000011,
80-
Text /* ********************* */ = 0b00_000100,
81-
ELEMENT_OR_TEXT_MASK /* ***** */ = 0b00_000101,
82-
TYPE_MASK /* **************** */ = 0b00_000111,
83-
INFLATED_TYPE_MASK /* ******* */ = 0b00_001111,
75+
Element /* ****************** */ = 0b00_0000001,
76+
Virtual /* ****************** */ = 0b00_0000010,
77+
ELEMENT_OR_VIRTUAL_MASK /* ** */ = 0b00_0000011,
78+
Text /* ********************* */ = 0b00_0000100,
79+
ELEMENT_OR_TEXT_MASK /* ***** */ = 0b00_0000101,
80+
TYPE_MASK /* **************** */ = 0b00_0000111,
81+
INFLATED_TYPE_MASK /* ******* */ = 0b00_0001111,
8482
/// Extra flag which marks if a node needs to be inflated.
85-
Inflated /* ***************** */ = 0b00_001000,
83+
Inflated /* ***************** */ = 0b00_0001000,
8684
/// Marks if the `ensureProjectionResolved` has been called on the node.
87-
Resolved /* ***************** */ = 0b00_010000,
85+
Resolved /* ***************** */ = 0b00_0010000,
8886
/// Marks if the vnode is deleted.
89-
Deleted /* ****************** */ = 0b00_100000,
87+
Deleted /* ****************** */ = 0b00_0100000,
88+
/// Marks if the vnode is a cursor (has priority set).
89+
Cursor /* ******************* */ = 0b00_1000000,
9090
/// Flags for Namespace
91-
NAMESPACE_MASK /* *********** */ = 0b11_000000,
92-
NEGATED_NAMESPACE_MASK /* ** */ = ~0b11_000000,
93-
NS_html /* ****************** */ = 0b00_000000, // http://www.w3.org/1999/xhtml
94-
NS_svg /* ******************* */ = 0b01_000000, // http://www.w3.org/2000/svg
95-
NS_math /* ****************** */ = 0b10_000000, // http://www.w3.org/1998/Math/MathML
91+
NAMESPACE_MASK /* *********** */ = 0b11_0000000,
92+
NEGATED_NAMESPACE_MASK /* ** */ = ~0b11_0000000,
93+
NS_html /* ****************** */ = 0b00_0000000, // http://www.w3.org/1999/xhtml
94+
NS_svg /* ******************* */ = 0b01_0000000, // http://www.w3.org/2000/svg
95+
NS_math /* ****************** */ = 0b10_0000000, // http://www.w3.org/1998/Math/MathML
9696
}
9797

9898
export const enum VNodeFlagsIndex {
99-
mask /* ************** */ = 0b11_111111,
100-
shift /* ************* */ = 8,
99+
mask /* ************** */ = 0b11_1111111,
100+
shift /* ************* */ = 9,
101101
}
102102

103103
export const enum VNodeProps {

0 commit comments

Comments
 (0)