[FIX] web: improve ListRenderer rendering speed

The ListRenderer disables the checkbox of all lines corresponding to a
record which cannot be selected. Unfortunately, because
`canSelectRecord` is a getter, it is invoked once per line, and this
getter in turns invokes the `editedRecord` getter which scans all record
to find which record is selected. This operation is O(n²), so it's very
slow when there are a lot of records.

This commit fixes that by computing the value once per render.

Time to render the list view of views (technical > User Interface >
views) with 600 records visible:
- before: ~1800ms
- after: ~250ms

closes odoo/odoo#149051

Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
This commit is contained in:
Samuel Degueldre
2024-01-11 17:00:54 +00:00
parent b05c6df09a
commit 8f1f32d0fb
@@ -2,6 +2,7 @@
<templates xml:space="preserve">
<t t-name="web.ListRenderer">
<t t-set="_canSelectRecord" t-value="canSelectRecord"/>
<div
class="o_list_renderer o_renderer table-responsive"
tabindex="-1"
@@ -14,7 +15,7 @@
<thead>
<tr>
<th t-if="hasSelectors" class="o_list_record_selector o_list_controller align-middle pe-1 cursor-pointer" tabindex="-1" t-on-keydown="(ev) => this.onCellKeydown(ev)" t-on-click.stop="toggleSelection">
<CheckBox disabled="!canSelectRecord" value="selectAll" className="'d-flex m-0'" onChange.bind="toggleSelection"/>
<CheckBox disabled="!_canSelectRecord" value="selectAll" className="'d-flex m-0'" onChange.bind="toggleSelection"/>
</th>
<t t-foreach="state.columns" t-as="column" t-key="column.id">
<th t-if="column.type === 'field'"
@@ -224,7 +225,7 @@
t-on-touchmove="() => this.onRowTouchMove(record)"
>
<td t-on-keydown="(ev) => this.onCellKeydown(ev, group, record)" t-if="hasSelectors" class="o_list_record_selector user-select-none" t-on-click.stop="() => this.toggleRecordSelection(record)" tabindex="-1">
<CheckBox disabled="!canSelectRecord" value="record.selected" onChange.alike="() => this.toggleRecordSelection(record)" />
<CheckBox disabled="!_canSelectRecord" value="record.selected" onChange.alike="() => this.toggleRecordSelection(record)" />
</td>
<t t-foreach="getColumns(record)" t-as="column" t-key="column.id">
<t t-if="column.type === 'field'">