[PERF] spreadsheet: avoid useless evaluation

Steps to reproduce:
- create a relational filter, let's say on `res.company`
- add a default value
- reference the filter in a cell with `=ODOO.FILTER.VALUE("my filter")`

=> every `ODOO.FILTER.VALUE` triggers an evaluation

With this commit, the re-evaluation after the data is fetched uses the
data source mechanism which only re-evaluates when all the data promises
are resolved, instead of evaluating after every resolved promise.

With this commit, the number of evaluations required when loading the
Timesheet report on our prod goes from 5 evaluations to only 3 (each evaluation
is 2-3s) because `ODOO.FILTER.VALUE("Company")` is present two times.

One issue this commit doesn't fix: there one RPC per `ODOO.FILTER.VALUE`
(can be fixed in master very easily because we refactored data fetching)

closes odoo/odoo#156495

Task: 3787125
Signed-off-by: Rémi Rahir (rar) <rar@odoo.com>
This commit is contained in:
Lucas Lefèvre (lul)
2024-03-05 18:06:25 +00:00
parent e1c79b6e22
commit 52c986ed19
@@ -49,6 +49,7 @@ export class GlobalFiltersUIPlugin extends spreadsheet.UIPlugin {
constructor(config) {
super(config);
this.orm = config.custom.env?.services.orm;
this.dataSources = config.custom.dataSources;
this.user = config.custom.env?.services.user;
/**
* Cache record display names for relation filters.
@@ -271,15 +272,13 @@ export class GlobalFiltersUIPlugin extends spreadsheet.UIPlugin {
return [[{ value: "" }]];
}
if (!this.recordsDisplayName[filter.id]) {
this.orm
const promise = this.orm
.call(filter.modelName, "read", [value, ["display_name"]])
.then((result) => {
const names = result.map(({ display_name }) => display_name);
this.recordsDisplayName[filter.id] = names;
this.dispatch("EVALUATE_CELLS", {
sheetId: this.getters.getActiveSheetId(),
});
});
this.dataSources.notifyWhenPromiseResolves(promise);
return [[{ value: "" }]];
}
return [[{ value: this.recordsDisplayName[filter.id].join(", ") }]];