From d046913a01ab0a4d664502598321f580c9dc6c2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Debongnie?= Date: Thu, 9 Jun 2022 13:29:28 +0200 Subject: [PATCH] [IMP] app: small scale perf improvement --- src/runtime/app.ts | 24 +++++++++--------------- src/runtime/component_node.ts | 13 +++++++++---- src/runtime/template_helpers.ts | 15 +++++++++------ 3 files changed, 27 insertions(+), 25 deletions(-) diff --git a/src/runtime/app.ts b/src/runtime/app.ts index 4d6c8488..311d2e74 100644 --- a/src/runtime/app.ts +++ b/src/runtime/app.ts @@ -130,29 +130,23 @@ export class App< return hasDynamicPropList && Object.keys(props1).length !== Object.keys(props2).length; } 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) => { let children = ctx.children; let node: any = children[key]; - - if (node && node.status === STATUS.DESTROYED) { + if ( + node && + (node.status === STATUS.DESTROYED || (isDynamic && node.component.constructor !== C)) + ) { node = undefined; } - if (isDynamic && node && node.component.constructor !== C) { - node = undefined; - } - const parentFiber = ctx.fiber!; if (node) { - let shouldRender = node.forceNextRender; - if (shouldRender) { + if (arePropsDifferent(node.props, props) || parentFiber.deep || node.forceNextRender) { node.forceNextRender = false; - } else { - const currentProps = node.props; - shouldRender = parentFiber.deep || arePropsDifferent(currentProps, props); - } - if (shouldRender) { - node.updateAndRender(props, parentFiber); + updateAndRender.call(node, props, parentFiber); } } else { // new component @@ -168,7 +162,7 @@ export class App< } node = new ComponentNode(C, props, this, ctx, key); children[key] = node; - node.initiateRender(new Fiber(node, parentFiber)); + initiateRender.call(node, new Fiber(node, parentFiber)); } parentFiber.childrenMap[key] = node; return node; diff --git a/src/runtime/component_node.ts b/src/runtime/component_node.ts index bc43fa37..a75b9ba5 100644 --- a/src/runtime/component_node.ts +++ b/src/runtime/component_node.ts @@ -321,10 +321,15 @@ export class ComponentNode

implements VNode 0; - this.children = this.fiber!.childrenMap; - this.bdom!.patch(this!.fiber!.bdom!, hasChildren); - this.fiber!.appliedToDom = true; + let hasChildren = false; + for (let _k in this.children) { + hasChildren = true; + break; + } + const fiber = this.fiber!; + this.children = fiber.childrenMap; + this.bdom!.patch(fiber.bdom!, hasChildren); + fiber.appliedToDom = true; this.fiber = null; } diff --git a/src/runtime/template_helpers.ts b/src/runtime/template_helpers.ts index c7ec6661..fb8b8790 100644 --- a/src/runtime/template_helpers.ts +++ b/src/runtime/template_helpers.ts @@ -5,6 +5,7 @@ import { isOptional, validateSchema } from "./validation"; import type { ComponentConstructor } from "./component"; import { markRaw } from "./reactivity"; +const ObjectCreate = Object.create; /** * This file contains utility functions that will be injected in each template, * to perform various useful tasks in the compiled code. @@ -26,7 +27,7 @@ function callSlot( key = key + "__slot_" + name; const slots = ctx.props.slots || {}; const { __render, __ctx, __scope } = slots[name] || {}; - const slotScope = Object.create(__ctx || {}); + const slotScope = ObjectCreate(__ctx || {}); if (__scope) { slotScope[__scope] = extra; } @@ -46,7 +47,7 @@ function callSlot( function capture(ctx: any): any { const component = ctx.__owl__.component; - const result = Object.create(component); + const result = ObjectCreate(component); for (let k in ctx) { result[k] = ctx[k]; } @@ -161,18 +162,20 @@ export function safeOutput(value: any): ReturnType { } let boundFunctions = new WeakMap(); +const WeakMapGet = WeakMap.prototype.get; +const WeakMapSet = WeakMap.prototype.set; function bind(ctx: any, fn: Function): Function { let component = ctx.__owl__.component; - let boundFnMap = boundFunctions.get(component); + let boundFnMap = WeakMapGet.call(boundFunctions, component); if (!boundFnMap) { 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) { boundFn = fn.bind(component); - boundFnMap.set(fn, boundFn); + WeakMapSet.call(boundFnMap, fn, boundFn); } return boundFn; }