대규모 데이터를 실시간으로 시각화하는 관제 대시보드. 가상 스크롤 테이블, WebSocket 실시간 차트, 커스텀 위젯 레이아웃.
IoT 센서 데이터, 서버 메트릭, 비즈니스 KPI를 하나의 대시보드에서 모니터링하는 관제 시스템입니다.
기술 구조:
• 데이터 레이어 — Go 서버가 ClickHouse에서 집계 쿼리를 실행하고, WebSocket으로 1초 간격 실시간 push
• 테이블 — TanStack Virtual로 10만 행 가상 스크롤. 컬럼 정렬, 필터, 고정(pin)을 서버 사이드에서 처리하여 클라이언트 메모리 절약
• 차트 — D3.js + Canvas 렌더링. SVG 대신 Canvas를 선택하여 수천 데이터포인트를 60fps로 렌더링
• 위젯 레이아웃 — react-grid-layout으로 드래그 기반 위젯 배치, 사용자별 레이아웃을 localStorage + 서버에 저장
WebSocket 메시지 폭주 — 50개 센서가 초당 1회씩 데이터를 보내면 초당 50개 메시지. 각 메시지마다 차트를 리렌더링하면 CPU 사용률이 100%에 도달.
D3.js 메모리 누수 — 대시보드를 오래 띄워놓으면 차트 데이터가 계속 축적되어 브라우저 탭 메모리가 시간당 200MB씩 증가. 24시간 모니터링 환경에서 브라우저 크래시 발생.
커스텀 위젯 리사이즈 시 차트 깨짐 — react-grid-layout에서 위젯 크기를 변경하면 D3.js 차트의 SVG viewBox가 즉시 반응하지 않아 차트가 잘리거나 빈 공간이 생김.
메시지 배칭 + RAF 스케줄링 — WebSocket 메시지를 100ms 윈도우로 배치(batch)하고, requestAnimationFrame 콜백에서 일괄 업데이트. 초당 50회 렌더링 → 최대 10회로 감소시키면서 데이터 누락 없이 실시간성 유지.
링 버퍼(Ring Buffer) 패턴 — 차트 데이터를 고정 길이 배열(최근 3,600개 = 1시간)로 관리. 새 데이터가 들어오면 가장 오래된 데이터를 덮어쓰는 순환 구조로 메모리 증가 완전 차단.
ResizeObserver + debounced reflow — 위젯 컨테이너에 ResizeObserver를 걸고, 리사이즈 완료 후 150ms debounce로 D3.js의 width/height를 업데이트하고 scales를 재계산. 리사이즈 중에는 CSS scale transform으로 임시 스케일링하여 시각적 끊김 방지.