[IMP] app: small scale perf improvement

This commit is contained in:
Géry Debongnie
2022-06-09 13:29:28 +02:00
committed by Sam Degueldre
parent 0e6059467f
commit d046913a01
3 changed files with 27 additions and 25 deletions
+9 -15
View File
@@ -130,29 +130,23 @@ export class App<
return hasDynamicPropList && Object.keys(props1).length !== Object.keys(props2).length; return hasDynamicPropList && Object.keys(props1).length !== Object.keys(props2).length;
} }
const arePropsDifferent = hasSlotsProp ? () => true : _arePropsDifferent; const arePropsDifferent = hasSlotsProp ? () => true : _arePropsDifferent;
const updateAndRender = ComponentNode.prototype.updateAndRender;
const initiateRender = ComponentNode.prototype.initiateRender;
return (props: P, key: string, ctx: ComponentNode, parent: any, C: any) => { return (props: P, key: string, ctx: ComponentNode, parent: any, C: any) => {
let children = ctx.children; let children = ctx.children;
let node: any = children[key]; let node: any = children[key];
if (
if (node && node.status === STATUS.DESTROYED) { node &&
(node.status === STATUS.DESTROYED || (isDynamic && node.component.constructor !== C))
) {
node = undefined; node = undefined;
} }
if (isDynamic && node && node.component.constructor !== C) {
node = undefined;
}
const parentFiber = ctx.fiber!; const parentFiber = ctx.fiber!;
if (node) { if (node) {
let shouldRender = node.forceNextRender; if (arePropsDifferent(node.props, props) || parentFiber.deep || node.forceNextRender) {
if (shouldRender) {
node.forceNextRender = false; node.forceNextRender = false;
} else { updateAndRender.call(node, props, parentFiber);
const currentProps = node.props;
shouldRender = parentFiber.deep || arePropsDifferent(currentProps, props);
}
if (shouldRender) {
node.updateAndRender(props, parentFiber);
} }
} else { } else {
// new component // new component
@@ -168,7 +162,7 @@ export class App<
} }
node = new ComponentNode(C, props, this, ctx, key); node = new ComponentNode(C, props, this, ctx, key);
children[key] = node; children[key] = node;
node.initiateRender(new Fiber(node, parentFiber)); initiateRender.call(node, new Fiber(node, parentFiber));
} }
parentFiber.childrenMap[key] = node; parentFiber.childrenMap[key] = node;
return node; return node;
+9 -4
View File
@@ -321,10 +321,15 @@ export class ComponentNode<P extends Props = any, E = any> implements VNode<Comp
} }
} }
_patch() { _patch() {
const hasChildren = Object.keys(this.children).length > 0; let hasChildren = false;
this.children = this.fiber!.childrenMap; for (let _k in this.children) {
this.bdom!.patch(this!.fiber!.bdom!, hasChildren); hasChildren = true;
this.fiber!.appliedToDom = true; break;
}
const fiber = this.fiber!;
this.children = fiber.childrenMap;
this.bdom!.patch(fiber.bdom!, hasChildren);
fiber.appliedToDom = true;
this.fiber = null; this.fiber = null;
} }
+9 -6
View File
@@ -5,6 +5,7 @@ import { isOptional, validateSchema } from "./validation";
import type { ComponentConstructor } from "./component"; import type { ComponentConstructor } from "./component";
import { markRaw } from "./reactivity"; import { markRaw } from "./reactivity";
const ObjectCreate = Object.create;
/** /**
* This file contains utility functions that will be injected in each template, * This file contains utility functions that will be injected in each template,
* to perform various useful tasks in the compiled code. * to perform various useful tasks in the compiled code.
@@ -26,7 +27,7 @@ function callSlot(
key = key + "__slot_" + name; key = key + "__slot_" + name;
const slots = ctx.props.slots || {}; const slots = ctx.props.slots || {};
const { __render, __ctx, __scope } = slots[name] || {}; const { __render, __ctx, __scope } = slots[name] || {};
const slotScope = Object.create(__ctx || {}); const slotScope = ObjectCreate(__ctx || {});
if (__scope) { if (__scope) {
slotScope[__scope] = extra; slotScope[__scope] = extra;
} }
@@ -46,7 +47,7 @@ function callSlot(
function capture(ctx: any): any { function capture(ctx: any): any {
const component = ctx.__owl__.component; const component = ctx.__owl__.component;
const result = Object.create(component); const result = ObjectCreate(component);
for (let k in ctx) { for (let k in ctx) {
result[k] = ctx[k]; result[k] = ctx[k];
} }
@@ -161,18 +162,20 @@ export function safeOutput(value: any): ReturnType<typeof toggler> {
} }
let boundFunctions = new WeakMap(); let boundFunctions = new WeakMap();
const WeakMapGet = WeakMap.prototype.get;
const WeakMapSet = WeakMap.prototype.set;
function bind(ctx: any, fn: Function): Function { function bind(ctx: any, fn: Function): Function {
let component = ctx.__owl__.component; let component = ctx.__owl__.component;
let boundFnMap = boundFunctions.get(component); let boundFnMap = WeakMapGet.call(boundFunctions, component);
if (!boundFnMap) { if (!boundFnMap) {
boundFnMap = new WeakMap(); boundFnMap = new WeakMap();
boundFunctions.set(component, boundFnMap); WeakMapSet.call(boundFunctions, component, boundFnMap);
} }
let boundFn = boundFnMap.get(fn); let boundFn = WeakMapGet.call(boundFnMap, fn);
if (!boundFn) { if (!boundFn) {
boundFn = fn.bind(component); boundFn = fn.bind(component);
boundFnMap.set(fn, boundFn); WeakMapSet.call(boundFnMap, fn, boundFn);
} }
return boundFn; return boundFn;
} }