[FIX] web: improve performance in list views with date/datetime fields

When rendering the list view, we evaluate the evalContext for each field
so that we can give it infos such as readonly, required, invalid or
empty. In doing so, date and datetime feels are serialized and added to
the evalContext, but serializing dates can be slow, especially when not
using the default English locale. Internally, luxon checks whether the
locale is English which instantiates an Intl object which can be slow
and this is compounded by the fact that the method is called hundreds of
time in a single render.

This commit caches serialized dates and datetimes in a WeakMap, as the
luxon Date objects are immutable, this is safe, and because these
objects are not recreated often, it also eliminates a lot of the calls
to luxon's toFormat. In the quotation list view, this brings the render
time from ~1100ms to ~270ms. While this is still slow and further work
will be undertaken to make the evalContext lazy (so that only
date/datetimes which are actually used are serialized), it is a good
first step and brings the performance back to a level where the list
view is reasonably usable.

closes odoo/odoo#110103

X-original-commit: 64eeeef4d3d93a9b2753520e0067aa7996988d4c
Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
This commit is contained in:
Samuel Degueldre
2023-01-17 12:58:59 +01:00
parent 3330215c4d
commit 76a44b29f5
+13 -2
View File
@@ -409,20 +409,31 @@ export function deserializeDateTime(value) {
return DateTime.fromSQL(value, { zone: "utc", numberingSystem: "latn" }).setZone("default");
}
const dateCache = new WeakMap();
/**
* Returns a serialized string representing the given date.
* @param {DateTime} value DateTime object, its timezone does not matter
* @returns {string} serialized date, ready to be sent to the server
*/
export function serializeDate(value) {
return value.toFormat(SERVER_DATE_FORMAT, { numberingSystem: "latn" });
if (!dateCache.has(value)) {
dateCache.set(value, value.toFormat(SERVER_DATE_FORMAT, { numberingSystem: "latn" }));
}
return dateCache.get(value);
}
const dateTimeCache = new WeakMap();
/**
* Returns a serialized string representing the given datetime.
* @param {DateTime} value DateTime object, its timezone does not matter
* @returns {string} serialized datetime, ready to be sent to the server
*/
export function serializeDateTime(value) {
return value.setZone("utc").toFormat(SERVER_DATETIME_FORMAT, { numberingSystem: "latn" });
if (!dateTimeCache.has(value)) {
dateTimeCache.set(
value,
value.setZone("utc").toFormat(SERVER_DATETIME_FORMAT, { numberingSystem: "latn" })
);
}
return dateTimeCache.get(value);
}