Files
odoo_source/addons/web/static/tests/views/form_benchmarks.js
T
Aaron Bohy 11857adec0 [IMP] web,barcodes: speed up form view rendering
Large form views (containing a lot of fields), e.g. the crm.lead
form view, take a while to render (~ 250 ms). Most form views
contain several (sometimes a lot) invisible fields (invisible="1"),
whose only purpose in the view is to be fetched, so that they can
be used to evalute domains and contexts.

This commit implements a trivial optimization of the form renderer,
which consists in skipping the rendering of those invisible fields.
With this change, we gain ~25% of rendering time on the crm.lead
form view.

closes odoo/odoo#54368

Related: odoo/enterprise#11875
Signed-off-by: Lucas Perais (lpe) <lpe@odoo.com>
2020-07-16 09:19:46 +00:00

109 lines
4.1 KiB
JavaScript

odoo.define('web.form_benchmarks', function (require) {
"use strict";
const FormView = require('web.FormView');
const testUtils = require('web.test_utils');
const { createView } = testUtils;
QUnit.module('Form View', {
beforeEach: function () {
this.data = {
foo: {
fields: {
foo: {string: "Foo", type: "char"},
many2many: { string: "bar", type: "many2many", relation: 'bar'},
},
records: [
{ id: 1, foo: "bar", many2many: []},
],
onchanges: {}
},
bar: {
fields: {
char: {string: "char", type: "char"},
many2many: { string: "pokemon", type: "many2many", relation: 'pokemon'},
},
records: [],
onchanges: {}
},
pokemon: {
fields: {
name: {string: "Name", type: "char"},
},
records: [],
onchanges: {}
},
};
this.arch = null;
this.run = function (assert, viewParams, cb) {
const data = this.data;
const arch = this.arch;
return new Promise(resolve => {
new Benchmark.Suite({})
.add('form', {
defer: true,
fn: async (deferred) => {
const form = await createView(Object.assign({
View: FormView,
model: 'foo',
data,
arch,
}, viewParams));
if (cb) {
await cb(form);
}
form.destroy();
deferred.resolve();
},
})
.on('cycle', event => {
assert.ok(true, String(event.target));
})
.on('complete', resolve)
.run({ async: true });
});
};
}
}, function () {
QUnit.test('x2many with 250 rows, 2 fields (with many2many_tags, and modifiers), onchanges, and edition', function (assert) {
assert.expect(1);
this.data.foo.onchanges.many2many = function (obj) {
obj.many2many = [5].concat(obj.many2many);
};
for (let i = 2; i < 500; i++) {
this.data.bar.records.push({
id: i,
char: "automated data",
});
this.data.foo.records[0].many2many.push(i);
}
this.arch = `
<form>
<field name="many2many">
<tree editable="top" limit="250">
<field name="char"/>
<field name="many2many" widget="many2many_tags" attrs="{'readonly': [('char', '==', 'toto')]}"/>
</tree>
</field>
</form>`;
return this.run(assert, { res_id: 1 }, async form => {
await testUtils.form.clickEdit(form);
await testUtils.dom.click(form.$('.o_data_cell:first'));
await testUtils.fields.editInput(form.$('input:first'), "tralala");
});
});
QUnit.test('form view with 100 fields, half of them being invisible', function (assert) {
assert.expect(1);
this.arch = `
<form>
${[...Array(100)].map((_, i) => '<field name="foo"' + (i % 2 ? ' invisible="1"' : '') + '/>').join('')}
</form>`;
return this.run(assert);
});
});
});