[IMP] web: add shouldUpdate=false to some components
We add in this commit a "decorator" to make components that do not rerender when their parent is updating them. This makes sense for some main components that knows before hand that they do not depend on a props change. This commit is mostly an optimization to avoid useless work by owl, but it also has some interesting properties: before this commit, each dialogs would be rerendered whenever a new dialog is added. This could be an issue if the rendering of one of them causes an error, which needs in turn to add a dialog, ... closes odoo-dev/odoo#970 Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
This commit is contained in:
committed by
Aaron Bohy
parent
ea0a718fb4
commit
97c88e8c06
@@ -7,6 +7,9 @@ class ErrorHandler extends Component {
|
||||
this.props.callback();
|
||||
throw error;
|
||||
}
|
||||
shouldUpdate() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
ErrorHandler.template = tags.xml`<t t-component="props.dialog.class" t-props="props.dialog.props" />`;
|
||||
|
||||
|
||||
@@ -9,6 +9,10 @@ export class Notification extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
shouldUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
get className() {
|
||||
let className;
|
||||
switch (this.props.type) {
|
||||
|
||||
@@ -19,6 +19,11 @@ class PopoverController extends Component {
|
||||
willUnmount() {
|
||||
this.targetObserver.disconnect();
|
||||
}
|
||||
|
||||
shouldUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
get popoverProps() {
|
||||
return {
|
||||
target: this.target,
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
const { Component, tags } = owl;
|
||||
|
||||
export function makeNonUpdatableComponent(Comp) {
|
||||
class NoUpdate extends Component {
|
||||
shouldUpdate() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
NoUpdate.template = tags.xml`<t t-component="Comp" t-props="props"/>`;
|
||||
NoUpdate.components = { Comp };
|
||||
|
||||
return NoUpdate;
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import { useBus } from "../core/bus_hook";
|
||||
import { ActionContainer } from "./actions/action_container";
|
||||
import { NavBar } from "./navbar/navbar";
|
||||
import { useEffect } from "@web/core/effect_hook";
|
||||
import { makeNonUpdatableComponent } from "../core/utils/components";
|
||||
|
||||
const { Component, hooks } = owl;
|
||||
const { useExternalListener } = hooks;
|
||||
@@ -19,7 +20,11 @@ export class WebClient extends Component {
|
||||
this.router = useService("router");
|
||||
this.user = useService("user");
|
||||
useService("legacy_service_provider");
|
||||
this.Components = mainComponentRegistry.getEntries();
|
||||
this.Components = mainComponentRegistry.getEntries().map(([name, elem]) => {
|
||||
const { Component, props } = elem;
|
||||
const NonUpdatableComp = makeNonUpdatableComponent(Component);
|
||||
return [name, { Component: NonUpdatableComp, props }];
|
||||
});
|
||||
this.title.setParts({ zopenerp: "Odoo" }); // zopenerp is easy to grep
|
||||
useBus(this.env.bus, "ROUTE_CHANGE", this.loadRouterState);
|
||||
useBus(this.env.bus, "ACTION_MANAGER:UI-UPDATED", (mode) => {
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { makeNonUpdatableComponent } from "@web/core/utils/components";
|
||||
import { makeTestEnv } from "../../helpers/mock_env";
|
||||
import { getFixture } from "../../helpers/utils";
|
||||
|
||||
const { Component, mount } = owl;
|
||||
|
||||
QUnit.module("utils", () => {
|
||||
QUnit.module("components");
|
||||
|
||||
QUnit.test("makeNonUpdatableComponent", async function (assert) {
|
||||
class Child extends Component {
|
||||
mounted() {
|
||||
assert.step("mounted");
|
||||
}
|
||||
willUpdateProps() {
|
||||
assert.step("willupdateprops");
|
||||
}
|
||||
}
|
||||
Child.template = owl.tags.xml`<div>hey</div>`;
|
||||
class Parent extends Component {}
|
||||
Parent.template = owl.tags.xml`<div><Child1/><Child2/></div>`;
|
||||
Parent.components = { Child1: Child, Child2: makeNonUpdatableComponent(Child) };
|
||||
|
||||
const target = getFixture();
|
||||
const parent = await mount(Parent, { env: makeTestEnv(), target });
|
||||
assert.verifySteps(["mounted", "mounted"]);
|
||||
|
||||
await parent.render();
|
||||
assert.verifySteps(["willupdateprops"]);
|
||||
parent.destroy();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user