From 81fe3c0d95f7b1a18fb22f91dba27d2324d36013 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Rahir=20=28rar=29?= Date: Tue, 10 Sep 2024 08:55:55 +0000 Subject: [PATCH] [PERF] model: avoid useless finalize on initialization MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, finalize will be called after each replay of a `stateUpdateMessage` during the Model instanciation. Depending on the type of revisions and on the number of cells to evaluate, this can end up having a devastating effect on the performance at first load. 2 examples: - on a spreadsheet on 450*26 cells (all filled) with 300 random but simple revisions, we spend 2.8 seconds in the evaluaion - A client spreadsheet in 16.0 with 1100 revisions cannot load due to a crash of the broweer tab This revision adds a "loading state" where the finalize is disabled and only used once after the replay of all stateUpdateMessages. closes odoo/o-spreadsheet#4969 Task: 4176216 X-original-commit: 512617b9987aa138101dedf3ccc6d63cd584c6fa Signed-off-by: Lucas Lefèvre (lul) Signed-off-by: Rémi Rahir (rar) --- src/model.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/model.ts b/src/model.ts index cb255025fa..9a5981f03b 100644 --- a/src/model.ts +++ b/src/model.ts @@ -114,6 +114,7 @@ export class Model extends EventBus implements CommandDispatcher { */ private renderers: [UIPlugin, LAYERS][] = []; + private isLoading: boolean; /** * Internal status of the model. Important for command handling coordination */ @@ -219,6 +220,11 @@ export class Model extends EventBus implements CommandDispatcher { this.selection.observe(this, { handleEvent: () => this.trigger("update"), }); + + // move in "Loading" mode where we ignore redundant calls to finalize triggered by the + // replay of stateUpdateMessages in the session + this.isLoading = true; + // This should be done after construction of LocalHistory due to order of // events this.setupSessionEvents(); @@ -233,6 +239,10 @@ export class Model extends EventBus implements CommandDispatcher { // mark all models as "raw", so they will not be turned into reactive objects // by owl, since we do not rely on reactivity markRaw(this); + + this.isLoading = false; + // ensure propre recomputation of plugin states after the message replays + this.finalize(); } joinSession() { @@ -368,6 +378,9 @@ export class Model extends EventBus implements CommandDispatcher { } private finalize() { + if (this.isLoading) { + return; + } this.status = Status.Finalizing; for (const h of this.handlers) { h.finalize();