Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Master small optimizations ged #1481

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 59 additions & 19 deletions src/runtime/blockdom/block_compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,17 @@ function normalizeNode(node: HTMLElement | Text) {
}
}

/**
* Encode 2 numbers and 1 boolean in a number, using 31 bits:
* n1 => encoded in 16 most significant bits
* n2 => encoded in 15 next bits
* boolean => encoded in last significant bit.
* This code assumes that n1 and n2 are small enough to fit in that number of bits
*/
function encodeValue(n1: number, n2: number, b: boolean): number {
return (((n1 << 15) | n2) << 1) | (b ? 1 : 0);
}

// -----------------------------------------------------------------------------
// building a intermediate tree
// -----------------------------------------------------------------------------
Expand Down Expand Up @@ -306,7 +317,7 @@ interface IndexedLocation extends Location {

interface Child {
parentRefIdx: number;
afterRefIdx?: number;
afterRefIdx: number;
isOnlyChild?: boolean;
}

Expand Down Expand Up @@ -374,6 +385,7 @@ function updateCtx(ctx: BlockCtx, tree: IntermediateTree) {
// tree is the parentnode here
ctx.children[info.idx] = {
parentRefIdx: info.refIdx!,
afterRefIdx: 0,
isOnlyChild: true,
};
} else {
Expand Down Expand Up @@ -501,7 +513,6 @@ function createBlockClass(template: HTMLElement, ctx: BlockCtx): BlockClass {
}));
const locN = locations.length;
const childN = children.length;
const childrenLocs = children;
const isDynamic = refN > 0;

// these values are defined here to make them faster to lookup in the class
Expand Down Expand Up @@ -556,19 +567,37 @@ function createBlockClass(template: HTMLElement, ctx: BlockCtx): BlockClass {
}

if (isDynamic) {
const nextSibling = nodeGetNextSibling;
const firstChild = nodeGetFirstChild;
const bitPackedCollectors = new Uint32Array(
collectors.map((c) => {
return encodeValue(c.idx, c.prevIdx, c.getVal === nextSibling);
})
);
const childrenLocs = new Uint32Array(
children.map((c) => {
return encodeValue(c.afterRefIdx, c.parentRefIdx, Boolean(c.isOnlyChild));
})
);

Block.prototype.mount = function mount(parent: HTMLElement, afterNode: Node | null) {
const el = nodeCloneNode.call(template, true);
// collecting references
const refs: Node[] = new Array(refN);
this.refs = refs;
refs[0] = el;
for (let i = 0; i < colN; i++) {
const w = collectors[i];
refs[w.idx] = w.getVal.call(refs[w.prevIdx]);
let info = bitPackedCollectors[i];
// decode info
const fn = (info & 1) === 1 ? nextSibling : firstChild;
info = info >> 1;
const prevIdx = info & 0b111111111111111;
const idx = info >> 15;
refs[idx] = fn.call(refs[prevIdx]);
}

// applying data to all update points
if (locN) {
if (locN !== 0) {
const data = this.data!;
for (let i = 0; i < locN; i++) {
const loc = locations[i];
Expand All @@ -579,15 +608,21 @@ function createBlockClass(template: HTMLElement, ctx: BlockCtx): BlockClass {
nodeInsertBefore.call(parent, el, afterNode);

// preparing all children
if (childN) {
if (childN !== 0) {
const children = this.children;
for (let i = 0; i < childN; i++) {
const child = children![i];
if (child) {
const loc = childrenLocs[i];
const afterNode = loc.afterRefIdx ? refs[loc.afterRefIdx] : null;
child.isOnlyChild = loc.isOnlyChild;
child.mount(refs[loc.parentRefIdx] as any, afterNode);
if (child !== undefined) {
let info = childrenLocs[i];
// decode info
const isOnlyChild = info & 1;
info = info >> 1;
const parentRefIdx = info & 0b111111111111111;
const afterRefIdx = info >> 15;

const afterNode = afterRefIdx !== 0 ? refs[afterRefIdx] : null;
child.isOnlyChild = isOnlyChild as any;
child.mount(refs[parentRefIdx] as any, afterNode);
}
}
}
Expand All @@ -601,7 +636,7 @@ function createBlockClass(template: HTMLElement, ctx: BlockCtx): BlockClass {
}
const refs = this.refs!;
// update texts/attributes/
if (locN) {
if (locN !== 0) {
const data1 = this.data!;
const data2 = other.data!;
for (let i = 0; i < locN; i++) {
Expand All @@ -616,14 +651,14 @@ function createBlockClass(template: HTMLElement, ctx: BlockCtx): BlockClass {
}

// update children
if (childN) {
if (childN !== 0) {
let children1 = this.children;
const children2 = other.children;
for (let i = 0; i < childN; i++) {
const child1 = children1![i];
const child2 = children2![i];
if (child1) {
if (child2) {
if (child1 !== undefined) {
if (child2 !== undefined) {
child1.patch(child2, withBeforeRemove);
} else {
if (withBeforeRemove) {
Expand All @@ -632,10 +667,15 @@ function createBlockClass(template: HTMLElement, ctx: BlockCtx): BlockClass {
child1.remove();
children1![i] = undefined;
}
} else if (child2) {
const loc = childrenLocs[i];
const afterNode = loc.afterRefIdx ? refs[loc.afterRefIdx] : null;
child2.mount(refs[loc.parentRefIdx] as any, afterNode);
} else if (child2 !== undefined) {
let info = childrenLocs[i];
// decode info
info = info >> 1;
const parentRefIdx = info & 0b111111111111111;
const afterRefIdx = info >> 15;

const afterNode = afterRefIdx !== 0 ? refs[afterRefIdx] : null;
child2.mount(refs[parentRefIdx] as any, afterNode);
children1![i] = child2;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/blockdom/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ function createElementHandler(evName: string, capture: boolean = false): EventHa
}

function remove(this: HTMLElement) {
delete (this as any)[eventKey];
(this as any)[eventKey] = false;
this.removeEventListener(evName, listener, { capture });
}
function update(this: HTMLElement, data: any) {
Expand Down
10 changes: 5 additions & 5 deletions src/runtime/blockdom/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class VList {
this.anchor = _anchor;
nodeInsertBefore.call(parent, _anchor, afterNode);
const l = children.length;
if (l) {
if (l !== 0) {
const mount = children[0].mount;
for (let i = 0; i < l; i++) {
mount.call(children[i], parent, _anchor);
Expand Down Expand Up @@ -186,7 +186,7 @@ class VList {
} else {
for (let i = startIdx1; i <= endIdx1; i++) {
let ch = ch1[i];
if (ch) {
if (ch !== null) {
if (withBeforeRemove) {
beforeRemove.call(ch);
}
Expand All @@ -200,7 +200,7 @@ class VList {
beforeRemove() {
const children = this.children;
const l = children.length;
if (l) {
if (l !== 0) {
const beforeRemove = children[0].beforeRemove;
for (let i = 0; i < l; i++) {
beforeRemove.call(children[i]);
Expand All @@ -215,7 +215,7 @@ class VList {
} else {
const children = this.children;
const l = children.length;
if (l) {
if (l !== 0) {
const remove = children[0].remove;
for (let i = 0; i < l; i++) {
remove.call(children[i]);
Expand All @@ -240,7 +240,7 @@ export function list(children: VNode[]): VNode<VList> {
}

function createMapping(ch1: any[], startIdx1: number, endIdx2: number): { [key: string]: any } {
let mapping: any = {};
const mapping: any = {};
for (let i = startIdx1; i <= endIdx2; i++) {
mapping[ch1[i].key] = i;
}
Expand Down
20 changes: 10 additions & 10 deletions src/runtime/blockdom/multi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export class VMulti {
const anchors = new Array(l);
for (let i = 0; i < l; i++) {
let child = children[i];
if (child) {
if (child !== undefined) {
child.mount(parent, afterNode);
} else {
const childAnchor = document.createTextNode("");
Expand All @@ -44,7 +44,7 @@ export class VMulti {
const anchors = this.anchors;
for (let i = 0, l = children.length; i < l; i++) {
let child = children[i];
if (child) {
if (child !== undefined) {
child.moveBeforeDOMNode(node, parent);
} else {
const anchor = anchors![i];
Expand All @@ -56,14 +56,14 @@ export class VMulti {
moveBeforeVNode(other: VMulti | null, afterNode: Node | null) {
if (other) {
const next = other!.children[0];
afterNode = (next ? next.firstNode() : other!.anchors![0]) || null;
afterNode = (next !== undefined ? next.firstNode() : other!.anchors![0]) || null;
}
const children = this.children;
const parent = this.parentEl;
const anchors = this.anchors;
for (let i = 0, l = children.length; i < l; i++) {
let child = children[i];
if (child) {
if (child !== undefined) {
child.moveBeforeVNode(null, afterNode);
} else {
const anchor = anchors![i];
Expand All @@ -83,8 +83,8 @@ export class VMulti {
for (let i = 0, l = children1.length; i < l; i++) {
const vn1 = children1[i];
const vn2 = children2[i];
if (vn1) {
if (vn2) {
if (vn1 !== undefined) {
if (vn2 !== undefined) {
vn1.patch(vn2, withBeforeRemove);
} else {
const afterNode = vn1.firstNode()!;
Expand All @@ -97,7 +97,7 @@ export class VMulti {
vn1.remove();
children1[i] = undefined;
}
} else if (vn2) {
} else if (vn2 !== undefined) {
children1[i] = vn2;
const anchor = anchors[i];
vn2.mount(parentEl, anchor);
Expand All @@ -110,7 +110,7 @@ export class VMulti {
const children = this.children;
for (let i = 0, l = children.length; i < l; i++) {
const child = children[i];
if (child) {
if (child !== undefined) {
child.beforeRemove();
}
}
Expand All @@ -125,7 +125,7 @@ export class VMulti {
const anchors = this.anchors;
for (let i = 0, l = children.length; i < l; i++) {
const child = children[i];
if (child) {
if (child !== undefined) {
child.remove();
} else {
nodeRemoveChild.call(parentEl, anchors![i]);
Expand All @@ -136,7 +136,7 @@ export class VMulti {

firstNode(): Node | undefined {
const child = this.children[0];
return child ? child.firstNode() : this.anchors![0];
return child !== undefined ? child.firstNode() : this.anchors![0];
}

toString(): string {
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/template_helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ function callSlot(
const slots = ctx.props.slots || {};
const { __render, __ctx, __scope } = slots[name] || {};
const slotScope = ObjectCreate(__ctx || {});
if (__scope) {
if (__scope !== undefined) {
slotScope[__scope] = extra;
}
const slotBDom = __render ? __render(slotScope, parent, key) : null;
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export type Callback = () => void;
export function batched(callback: Callback): Callback {
let scheduled = false;
return async (...args) => {
if (!scheduled) {
if (scheduled === false) {
scheduled = true;
await Promise.resolve();
scheduled = false;
Expand Down