Fix radar blip flicker by deferring renders during hover

The innerHTML rebuild on every SSE event was destroying and recreating
DOM elements under the cursor, causing rapid mouseenter/mouseleave
cycling. Now defers DOM rebuilds while hovering and debounces rapid
update calls with a 200ms window.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Smittix
2026-02-04 23:43:19 +00:00
parent ce88b7c5f1
commit 5870b5e735
+24 -3
View File
@@ -33,6 +33,9 @@ const ProximityRadar = (function() {
let activeFilter = null; let activeFilter = null;
let onDeviceClick = null; let onDeviceClick = null;
let selectedDeviceKey = null; let selectedDeviceKey = null;
let isHovered = false;
let renderPending = false;
let renderTimer = null;
/** /**
* Initialize the radar component * Initialize the radar component
@@ -162,8 +165,18 @@ const ProximityRadar = (function() {
devices.set(device.device_key, device); devices.set(device.device_key, device);
}); });
// Apply filter and render // Defer render while user is hovering to prevent DOM rebuild flicker
renderDevices(); if (isHovered) {
renderPending = true;
return;
}
// Debounce rapid updates (e.g. per-device SSE events)
if (renderTimer) clearTimeout(renderTimer);
renderTimer = setTimeout(() => {
renderTimer = null;
renderDevices();
}, 200);
} }
/** /**
@@ -232,7 +245,7 @@ const ProximityRadar = (function() {
devicesGroup.innerHTML = dots; devicesGroup.innerHTML = dots;
// Attach click handlers // Attach event handlers
devicesGroup.querySelectorAll('.radar-device').forEach(el => { devicesGroup.querySelectorAll('.radar-device').forEach(el => {
el.addEventListener('click', (e) => { el.addEventListener('click', (e) => {
const deviceKey = el.getAttribute('data-device-key'); const deviceKey = el.getAttribute('data-device-key');
@@ -240,6 +253,14 @@ const ProximityRadar = (function() {
onDeviceClick(deviceKey); onDeviceClick(deviceKey);
} }
}); });
el.addEventListener('mouseenter', () => { isHovered = true; });
el.addEventListener('mouseleave', () => {
isHovered = false;
if (renderPending) {
renderPending = false;
renderDevices();
}
});
}); });
} }