Running Hikvision's IoT Frontend: Video Streams, 50K Devices, and 24/7 Stability
IoT dashboards are a stress test for browser limits: GPU memory, WebRTC connection caps, and garbage collection pauses all surface as real crashes on 24/7 screens. The patterns here — batched state, shallow reactivity, shared WebSocket in micro-frontends — apply to any dashboard that must stay alive under a firehose of real-time data.
A Hikvision IoT platform frontend must render 16 simultaneous low-latency video feeds, track real-time status for up to 50,000 devices, and run continuously without memory leaks. Video playback relies on WebRTC for sub-second preview and HLS for recorded playback, with IntersectionObserver pausing off-screen streams to conserve GPU memory. Device state arrives over a single WebSocket and is buffered into requestAnimationFrame batches; a shallow-reactive Map ensures a status change re-renders only the affected list item, not the entire virtual list.
Real-time sensor charts use ECharts with animation disabled, a rolling 300-point window, and incremental setOption calls. On maps, marker clustering and CSS-only status updates prevent DOM churn when hundreds of cameras change state. A unified resource manager tracks all intervals, WebSocket connections, and AbortControllers, cleaning them up on component unmount. Memory monitoring triggers an automatic page refresh when JS heap usage exceeds 85%.
Micro-frontends split video, access control, alarms, and analytics into separate repos, but a shared WebSocket in the shell app prevents connection multiplication. Security measures include short-lived stream tokens, Canvas-based employee-ID watermarks, and field-level data masking per user role.
GPU memory is the hard ceiling for multi-camera dashboards, not JavaScript performance. A 16-up view can exhaust 1.5 GB of VRAM on integrated graphics before any CPU bottleneck appears.
The shallow-reactive Map pattern is a useful alternative to state-management libraries for high-frequency updates: it sidesteps deep-proxy overhead and keeps re-render scope to a single list cell.
Auto-refreshing the page when memory hits 85% is a pragmatic admission that browser GC is unpredictable. It trades a brief interruption for avoiding a hard crash on an unattended screen.
Sharing one WebSocket across micro-frontends via a global event bus solves a real architectural cost: without it, each sub-app opens its own connection, and a 4-sub-app dashboard burns through browser connection limits fast.