From f0928cda55046b0a9bcfb8ebf2c4f356b05bf83a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Theys?= Date: Wed, 20 Dec 2023 12:54:06 +0100 Subject: [PATCH] [FIX] mail: optimize onChange by accessing reactive only once Access `proxy[key]` only once to avoid triggering reactive `get()` many times, as this will be triggered in cascade to all elements in the chain in internal code, saving possibly dozens of uncessary calls per callback. Part-of: odoo/odoo#147814 --- addons/mail/static/src/core/common/record.js | 13 +++++++------ addons/mail/static/src/utils/common/misc.js | 13 +++++++------ 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/addons/mail/static/src/core/common/record.js b/addons/mail/static/src/core/common/record.js index 22d7018c0fc..da30a0ee8e4 100644 --- a/addons/mail/static/src/core/common/record.js +++ b/addons/mail/static/src/core/common/record.js @@ -1226,13 +1226,14 @@ export class Record { static _onChange(record, key, callback) { let proxy; function _observe() { - void proxy[key]; - if (proxy[key] instanceof Object) { - void Object.keys(proxy[key]); + // access proxy[key] only once to avoid triggering reactive get() many times + const val = proxy[key]; + if (typeof val === "object" && val !== null) { + void Object.keys(val); } - if (proxy[key] instanceof Array) { - void proxy[key].length; - void proxy[key].forEach((i) => i); + if (Array.isArray(val)) { + void val.length; + void val.forEach((i) => i); } } if (Array.isArray(key)) { diff --git a/addons/mail/static/src/utils/common/misc.js b/addons/mail/static/src/utils/common/misc.js index 5bc52ddf52a..025f5b8f610 100644 --- a/addons/mail/static/src/utils/common/misc.js +++ b/addons/mail/static/src/utils/common/misc.js @@ -40,13 +40,14 @@ export function isDragSourceExternalFile(dataTransfer) { export function onChange(target, key, callback) { let proxy; function _observe() { - void proxy[key]; - if (proxy[key] instanceof Object) { - void Object.keys(proxy[key]); + // access proxy[key] only once to avoid triggering reactive get() many times + const val = proxy[key]; + if (typeof val === "object" && val !== null) { + void Object.keys(val); } - if (proxy[key] instanceof Array) { - void proxy[key].length; - void proxy[key].forEach((i) => i); + if (Array.isArray(val)) { + void val.length; + void val.forEach((i) => i); } } if (Array.isArray(key)) {