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;
}