mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
big change: shallow render
With this commit, component only render child components if they have different props (shallow equality). Otherwise, we trust the reactivity system to make sure that all impacted components are updated
This commit is contained in:
@@ -948,7 +948,7 @@ export class CodeGenerator {
|
||||
let propString = propStr;
|
||||
if (ast.dynamicProps) {
|
||||
if (!props.length) {
|
||||
propString = `${compileExpr(ast.dynamicProps)}`;
|
||||
propString = `Object.assign({}, ${compileExpr(ast.dynamicProps)})`;
|
||||
} else {
|
||||
propString = `Object.assign({}, ${compileExpr(ast.dynamicProps)}, ${propStr})`;
|
||||
}
|
||||
@@ -1012,7 +1012,7 @@ export class CodeGenerator {
|
||||
keyArg = `${ctx.tKeyExpr} + ${keyArg}`;
|
||||
}
|
||||
const blockArgs = `${expr}, ${propString}, ${keyArg}, node, ctx`;
|
||||
let blockExpr = `component(${blockArgs})`;
|
||||
let blockExpr = `component(${blockArgs}${hasSlot ? ", true" : ""})`;
|
||||
if (Object.keys(extraArgs).length) {
|
||||
this.shouldDefineAssign = true;
|
||||
const content = Object.keys(extraArgs).map((k) => `${k}: ${extraArgs[k]}`);
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import type { Env } from "../app/app";
|
||||
import type { ComponentNode } from "./component_node";
|
||||
|
||||
export type Props = { [key: string]: any };
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Component Class
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { App, Env } from "../app/app";
|
||||
import { BDom, VNode } from "../blockdom";
|
||||
import { Component } from "./component";
|
||||
import { Component, Props } from "./component";
|
||||
import {
|
||||
Fiber,
|
||||
makeChildFiber,
|
||||
@@ -15,12 +15,21 @@ import { applyDefaultProps } from "./props_validation";
|
||||
import { STATUS } from "./status";
|
||||
import { applyStyles } from "./style";
|
||||
|
||||
function arePropsDifferent(props1: Props, props2: Props): boolean {
|
||||
for (let k in props1) {
|
||||
if (props1[k] !== props2[k]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
export function component(
|
||||
name: string | typeof Component,
|
||||
props: any,
|
||||
key: string,
|
||||
ctx: ComponentNode,
|
||||
parent: any
|
||||
parent: any,
|
||||
hasSlots: boolean = false
|
||||
): ComponentNode {
|
||||
let node: any = ctx.children[key];
|
||||
let isDynamic = typeof name !== "string";
|
||||
@@ -39,7 +48,9 @@ export function component(
|
||||
|
||||
const parentFiber = ctx.fiber!;
|
||||
if (node) {
|
||||
node.updateAndRender(props, parentFiber);
|
||||
if (hasSlots || arePropsDifferent(node.component.props, props)) {
|
||||
node.updateAndRender(props, parentFiber);
|
||||
}
|
||||
} else {
|
||||
// new component
|
||||
let C;
|
||||
@@ -241,6 +252,10 @@ export class ComponentNode<T extends typeof Component = typeof Component>
|
||||
}
|
||||
|
||||
patch() {
|
||||
if (!this.fiber) {
|
||||
// component was not rendered => no need to do anything
|
||||
return;
|
||||
}
|
||||
this.bdom!.patch(this!.fiber!.bdom!, false);
|
||||
this.fiber!.appliedToDom = true;
|
||||
this.fiber = null;
|
||||
|
||||
Reference in New Issue
Block a user