diff --git a/templates/adsb_dashboard.html b/templates/adsb_dashboard.html
index 27062c1..965dcc7 100644
--- a/templates/adsb_dashboard.html
+++ b/templates/adsb_dashboard.html
@@ -553,6 +553,7 @@
0 AIRCRAFT
-
-
+ const now = Date.now();
+ const canRebuild = now - lastFullRebuild > MIN_REBUILD_INTERVAL;
+
+ // Only do full rebuild if order changed AND enough time has passed
+ if (orderChanged && canRebuild) {
+ lastFullRebuild = now;
+ // Use DocumentFragment for efficient batch insert
+ const fragment = document.createDocumentFragment();
+
+ sortedAircraft.forEach(ac => {
+ const div = document.createElement('div');
+ div.className = `aircraft-item ${selectedIcao === ac.icao ? 'selected' : ''}`;
+ div.setAttribute('data-icao', ac.icao);
+ div.onclick = () => selectAircraft(ac.icao);
+ div.innerHTML = buildAircraftItemHTML(ac);
+ fragment.appendChild(div);
+ });
+
+ container.innerHTML = '';
+ container.appendChild(fragment);
+ renderedAircraftOrder = newOrder;
+ } else {
+ // Incremental update - only update existing items in place
+ // Build a map of existing items to avoid repeated querySelector calls
+ const existingItems = {};
+ container.querySelectorAll('[data-icao]').forEach(el => {
+ existingItems[el.getAttribute('data-icao')] = el;
+ });
+
+ sortedAircraft.forEach(ac => {
+ const existingItem = existingItems[ac.icao];
+ if (existingItem) {
+ // Update selection state
+ existingItem.className = `aircraft-item ${selectedIcao === ac.icao ? 'selected' : ''}`;
+ // Update inner content
+ existingItem.innerHTML = buildAircraftItemHTML(ac);
+ }
+ });
+ }
+ }
+
+ function buildAircraftItemHTML(ac) {
+ const callsign = ac.callsign || '------';
+ const alt = ac.altitude ? ac.altitude.toLocaleString() : '---';
+ const speed = ac.speed || '---';
+ const heading = ac.heading ? ac.heading + '°' : '---';
+
+ return `
+
+
+
- `;
- }).join('');
+
+
+
+ `;
}
function selectAircraft(icao) {
@@ -990,6 +1083,7 @@
function cleanupOldAircraft() {
const now = Date.now();
const timeout = 60000; // 60 seconds
+ let needsUpdate = false;
Object.keys(aircraft).forEach(icao => {
if (now - aircraft[icao].lastSeen > timeout) {
@@ -1000,6 +1094,7 @@
}
// Remove aircraft
delete aircraft[icao];
+ needsUpdate = true;
// Clear selection if this was selected
if (selectedIcao === icao) {
@@ -1009,8 +1104,10 @@
}
});
- updateStats();
- renderAircraftList();
+ // Use batched update instead of direct calls
+ if (needsUpdate) {
+ scheduleUIUpdate();
+ }
}