[FIX] web: improve editable list view rendering speed

The editable list view may be really new, but it still suffers from a
performance issue.  The problem is that we need to evaluate modifiers
for a (sometimes) large number of fields: a list view with 80 rows and 7
columns has 560 field values.  This is not so large, but each of these
evaluation is still costly.

In particular, it needs to compute the evaluation context.  However, the
evaluation context is the same between all fields of the same record, so
in that case, the web framework does way too much work (with 7 columns,
it is 7 times too much).

This commit does not totally fix the issue, but it helps quite a lot.
What we do is just memoize the evalcontext computation. This means that
it will be evaluated only the first time it is needed, then will be kept
in memory.

Note that this is a fix, not an imp. The list view should be fast...
This commit is contained in:
Géry Debongnie
2017-05-04 13:45:26 +02:00
parent 7d26d244a4
commit 0d5d9fa3f5
3 changed files with 9 additions and 2 deletions
@@ -360,6 +360,13 @@ var BasicModel = AbstractModel.extend({
if (this.isNew(element.id)) {
delete element.res_id;
}
var evalContext;
Object.defineProperty(element, 'evalContext', {
get: function () {
evalContext = evalContext || self._getEvalContext(record);
return evalContext;
},
});
}
if (element.type === 'list') {
// apply changes if any
@@ -282,7 +282,7 @@ var BasicRenderer = AbstractRenderer.extend({
* @param {Object} record
*/
_computeModifiers: function (modifiersData, record) {
var evalContext = record.getEvalContext();
var evalContext = record.evalContext;
modifiersData.evaluatedModifiers[record.id]
= _.mapObject(modifiersData.modifiers, function (modifier) {
return new Domain(modifier, evalContext).compute(evalContext);
@@ -90,7 +90,7 @@ var KanbanRecord = Widget.extend({
* @returns {boolean} the domain evaluted with the current values
*/
_computeDomain: function (d) {
return new Domain(d).compute(this.state.getEvalContext());
return new Domain(d).compute(this.state.evalContext);
},
/**
* Generates the color classname from a given variable