mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2025-06-27 17:09:53 -04:00
WebUI: Improve performance of re-sorting table rows
This change drastically improves the performance of changing a table's sorted column. This performance is achieved through improved data structures, namely removing operations that repeatedly spliced an array. We also no longer iterate over a potentially large array. On a torrent with ~50,000 files, re-rendering after a sort improves from ~20 seconds to 2 seconds. PR #22827.
This commit is contained in:
parent
d7a5430893
commit
406a389d7c
1 changed files with 32 additions and 25 deletions
|
@ -858,42 +858,49 @@ window.qBittorrent.DynamicTable ??= (() => {
|
|||
}
|
||||
else {
|
||||
const trs = [...this.getTrs()];
|
||||
const trMap = new Map(trs.map(tr => [tr.rowId, tr]));
|
||||
|
||||
for (let rowPos = 0; rowPos < rows.length; ++rowPos) {
|
||||
const rowId = rows[rowPos].rowId;
|
||||
let tr_found = false;
|
||||
for (let j = rowPos; j < trs.length; ++j) {
|
||||
if (trs[j].rowId === rowId) {
|
||||
tr_found = true;
|
||||
if (rowPos === j)
|
||||
break;
|
||||
trs[j].inject(trs[rowPos], "before");
|
||||
const tmpTr = trs[j];
|
||||
trs.splice(j, 1);
|
||||
trs.splice(rowPos, 0, tmpTr);
|
||||
break;
|
||||
}
|
||||
const existingTr = trMap.get(rowId);
|
||||
if (existingTr !== undefined) {
|
||||
this.updateRow(existingTr, fullUpdate);
|
||||
}
|
||||
if (tr_found) { // row already exists in the table
|
||||
this.updateRow(trs[rowPos], fullUpdate);
|
||||
}
|
||||
else { // else create a new row in the table
|
||||
else {
|
||||
const tr = this.createRowElement(rows[rowPos]);
|
||||
|
||||
// Insert
|
||||
if (rowPos >= trs.length) {
|
||||
tr.inject(this.tableBody);
|
||||
trs.push(tr);
|
||||
}
|
||||
else {
|
||||
tr.inject(trs[rowPos], "before");
|
||||
trs.splice(rowPos, 0, tr);
|
||||
}
|
||||
// TODO look into using DocumentFragment or appending all trs at once for add'l performance gains
|
||||
// add to end of table - we'll move into the proper order later
|
||||
this.tableBody.appendChild(tr);
|
||||
trMap.set(rowId, tr);
|
||||
|
||||
this.updateRow(tr, true);
|
||||
}
|
||||
}
|
||||
|
||||
// reorder table rows
|
||||
let prevTr = null;
|
||||
for (let rowPos = 0; rowPos < rows.length; ++rowPos) {
|
||||
const { rowId } = rows[rowPos];
|
||||
const tr = trMap.get(rowId);
|
||||
|
||||
const isInCorrectLocation = rowId === trs[rowPos]?.rowId;
|
||||
if (!isInCorrectLocation) {
|
||||
// move row into correct location
|
||||
if (prevTr === null) {
|
||||
// insert as first row in table
|
||||
if (trs.length === 0)
|
||||
this.tableBody.append(tr);
|
||||
else
|
||||
trs[0].before(tr);
|
||||
}
|
||||
else {
|
||||
prevTr.after(tr);
|
||||
}
|
||||
}
|
||||
prevTr = tr;
|
||||
}
|
||||
|
||||
const rowPos = rows.length;
|
||||
|
||||
while ((rowPos < trs.length) && (trs.length > 0))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue