perf(website): cache sort values and batch DOM appends in sortRows

Calling getSortValue inside the comparator ran DOM queries on every
comparison (O(n log n) reads). Hoisting into a forEach beforehand reduces
that to O(n). Batching row appends through a DocumentFragment also avoids
repeated reflows during table reorder.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Vinta Chen 2026-03-22 01:32:21 +08:00
parent d36f1ed8d1
commit 3d9c2ae507
No known key found for this signature in database
GPG Key ID: B93DE4F003C33630

View File

@ -143,29 +143,36 @@ function getSortValue(row, col) {
function sortRows() {
var arr = Array.prototype.slice.call(rows);
if (activeSort) {
arr.sort(function (a, b) {
var aVal = getSortValue(a, activeSort.col);
var bVal = getSortValue(b, activeSort.col);
if (activeSort.col === 'name') {
var cmp = aVal < bVal ? -1 : aVal > bVal ? 1 : 0;
if (cmp === 0) return a._origIndex - b._origIndex;
return activeSort.order === 'desc' ? -cmp : cmp;
}
if (aVal <= 0 && bVal <= 0) return a._origIndex - b._origIndex;
if (aVal <= 0) return 1;
if (bVal <= 0) return -1;
var cmp = aVal - bVal;
if (cmp === 0) return a._origIndex - b._origIndex;
return activeSort.order === 'desc' ? -cmp : cmp;
});
} else {
arr.sort(function (a, b) { return a._origIndex - b._origIndex; });
}
var col = activeSort.col;
var order = activeSort.order;
// Cache sort values once to avoid DOM queries per comparison
arr.forEach(function (row) {
tbody.appendChild(row);
tbody.appendChild(row._expandRow);
row._sortVal = getSortValue(row, col);
});
arr.sort(function (a, b) {
var aVal = a._sortVal;
var bVal = b._sortVal;
if (col === 'name') {
var cmp = aVal < bVal ? -1 : aVal > bVal ? 1 : 0;
if (cmp === 0) return a._origIndex - b._origIndex;
return order === 'desc' ? -cmp : cmp;
}
if (aVal <= 0 && bVal <= 0) return a._origIndex - b._origIndex;
if (aVal <= 0) return 1;
if (bVal <= 0) return -1;
var cmp = aVal - bVal;
if (cmp === 0) return a._origIndex - b._origIndex;
return order === 'desc' ? -cmp : cmp;
});
var frag = document.createDocumentFragment();
arr.forEach(function (row) {
frag.appendChild(row);
frag.appendChild(row._expandRow);
});
tbody.appendChild(frag);
applyFilters();
}