21.6.3.3 슬라이스(Slice) 기반 배열 크기 통제 및 프론트엔드 차트 객체 렌더링 병목 차단
LTTB 다운샘플링(21.6.3.2장 참조)을 적용하여 800만 개의 데이터 덩어리를 1,000개로 찍어 누름으로써 거대한 DOM 크래시를 방어해 냈다.
하지만 LTTB 수학 연산 자체도 결코 공짜가 아니다. 1초에 60프레임씩 끝없이 새파란 최신 WebSocket 피가 쏟아져 들어와 배열 뒤에(Push) 박히고 있는데, 그때마다 누적된 수백만 개짜리 전체 원본 배열(Raw Array)을 꺼내서 매번 수학 공식을 돌리려 든다면, 다운샘플링을 하기 전 이미 그 무식한 반복 연산 부하 자체로 메인 스레드가 질식해 버린다.
본 절에서는 “우리는 과거의 무한한 영속을 관제하는 것이 아니라, 살아 숨 쉬는 현재의 스냅샷만을 통제한다” 는 비정한 철학 아래, 차트의 시야각(Window) 바깥으로 밀려난 과거 데이터들을 가차 없이 절단해 내는 FIFO(First-In-First-Out) 슬라이스 윈도우(Slice Window) 파괴 런북을 갈파한다.
1. 무한의 저주: 배열 길이 폭주와 React의 절망
상태 관리자(Zustand)에 계속해서 데이터를 넣는 행위는 독을 채우는 행위다.
array.push(new_data) 만 무한루프로 박아둔 대시보드를 24시간 켜둔다고 가정해 보자.
처음 1분은 멀쩡하던 화면이, 배열 사이즈가 10만 개를 넘어서면서 데이터가 1개 더 들어올 때마다 React 엔진이 10만 개짜리 배열 메모리 트리를 얕은 비교(Shallow Compare)해야 하는 연산 지옥에 처박힌다. 화면 차트가 뻣뻣하게(Stuttering) 굳기 시작한다.
무한(Infinity)한 데이터를 보유하려는 강박은 클라우드 데이터베이스(InfluxDB) 의 임무이지, 1.4GB 의 가냘픈 메모리에 의존하는 프론트엔드 관제 브라우저가 넘볼 영역이 아니다.
2. 시야각의 강제 축소와 Sliding Window 의 도륙
아키텍트는 대시보드 화면상에서 인간이 시각적으로 인지할 수 있는 ‘최대 관측 시간(최근 1시간 등)’ 을 정의하고, 그 밖으로 한 치라도 삐져나온 썩은 과거의 바이트들은 수신 즉시 목을 쳐내버린다(slice).
// [무한정 팽창하는 상태 저장소의 강제 슬라이싱 절단 런북]
// 차트에 그릴 최대 허용 마지노선 사이즈 (예: 최근 5,000개 포인트)
const MAX_DATA_POINTS = 5000;
const useRobotStore = create((set) => ({
telemetrySeries: [], // 실시간 피가 도는 동맥
appendData: (newData) => set((state) => {
// 일단 새로 들어온 데이터를 뒤에 붙인다.
let updatedSeries = [...state.telemetrySeries, newData];
// [절단의 철권]
// 배열 길이가 내가 허용한 최대 사이즈(5000)를 넘어서는 그 찰나!
if (updatedSeries.length > MAX_DATA_POINTS) {
// 맨 앞의 썩은 과거 피(오래된 데이터)를 냉정하게 잘라내 버린다! (Slice)
// 배열 길이는 영원히 5000개 언저리를 맴돌며 락온(Lock-on)된다.
updatedSeries = updatedSeries.slice(updatedSeries.length - MAX_DATA_POINTS);
}
return { telemetrySeries: updatedSeries };
})
}));
3. 메모리 연산 락온(Lock-On)과 렌더링 스루풋의 해방
이 slice 기반 슬라이딩 윈도우(Sliding Window) 빗장문 하나가 투입되었을 때, Websocket 에서 쏟아지는 파동이 초당 백 개든, 천 개든 프론트엔드 엔진의 처리 시간은 O(1) 에 근접한 완전한 상수(Constant) 시간 단위로 평형을 되찾는다.
- 웹소켓 수신 \rightarrow 2.
Push(1개 추가) \rightarrow 3.Slice(1개 삭제).
차트가 짊어지는 렌더링 엔진(Recharts/Chart.js) 앞단에 도달하는 데이터 배열은 죽었다 깨어나도[5000개]라는 덩치를 절대 벗어나지 않는다.
React 의 Virtual DOM 대조(Diffing) 비용은 1시간이 지나건 10년이 지나건 완전히 똑같은5000개루프 타임을 소모하게 되는 압도적 항상성(Homeostasis)의 기적을 이룬다.
이것이야말로 통신단(Zenoh)에서 미친 속도의 스루풋으로 폭격을 가할 때, 그 피격점인 브라우저가 화면 렌더링 템포를 지연 없이 사수할 수 있는 유일한 숨통이다. 시스템의 안정성은 데이터를 수집하는 집착에서 오는 것이 아니라, 내가 렌더링할 수 있는 물리적 포화선을 선언하고 그 너머의 과거를 가차 없이 삭제(Discard)해 버릴 수 있는 ‘파괴의 결단력’ 에서 완성된다.