WebGPU가 드디어 실전 영역으로: ChartGPU로 보는 대용량 데이터 시각화의 미래


솔직히 말해봅시다. 브라우저에서 차트를 그리는 건 여전히 고통스러운 일입니다. 데이터 포인트가 몇 백 개라면 SVG(D3.js)로 충분하고 예쁘게 만들 수 있죠. 하지만 데이터가 1만 개를 넘어가기 시작하면 Canvas API를 직접 건드려야 하고, 10만 개, 100만 개 단위로 넘어가면 그때부터는 ‘지옥의 최적화’ 게임이 시작됩니다.

최근 Hacker News에서 꽤 흥미로운 프로젝트 하나가 1위에 올랐습니다. 바로 ChartGPU 입니다. 이름에서 알 수 있듯 WebGPU를 기반으로 한 차트 라이브러리인데, ‘100만 개의 포인트를 60fps로 렌더링한다’ 는 대담한 주장을 들고나왔습니다.

오늘은 이 라이브러리의 내부 구조를 뜯어보고, 시니어 엔지니어 관점에서 이게 과연 ‘실전 투입 가능한 물건’인지, 아니면 그저 ‘화려한 데모’인지 분석해보려 합니다.

WebGPU, 그래픽스 그 이상을 향해

WebGPU는 WebGL의 후계자이지만, 단순히 그래픽 API의 업그레이드 버전이 아닙니다. Compute Shader를 브라우저에서 네이티브에 가까운 성능으로 돌릴 수 있다는 점이 핵심이죠. ChartGPU는 이 점을 파고들었습니다.

이 라이브러리의 아키텍처를 살펴보면 꽤 합리적인 구조를 취하고 있습니다:

  • Render Coordinator: 레이아웃, 스케일 계산, 데이터 업로드를 총괄합니다.
  • WGSL Shaders: 실제 렌더링은 Grid, Area, Bar, Line 등 각 차트 타입에 최적화된 WGSL 쉐이더가 담당합니다.
  • Interaction: 줌, 팬, 툴팁 같은 인터랙션은 Canvas 이벤트와 GPU 좌표계를 매핑해서 처리합니다.

특히 인상적인 건 스트리밍 업데이트 기능입니다. 금융 데이터나 IoT 센서 데이터처럼 실시간으로 쏟아지는 데이터를 appendData(...) 메서드로 밀어 넣으면, GPU 버퍼를 효율적으로 갱신하며 그려냅니다. 데모에서는 500만 개의 캔들스틱 차트를 100fps 이상으로 돌리는 퍼포먼스를 보여줍니다.

100만 데이터 포인트의 함정 (The Reality Check)

하지만 숫자에만 현혹되어서는 안 됩니다. HN 스레드에서도 이 부분에 대한 날카로운 지적들이 쏟아졌는데, 특히 uPlot(Canvas 기반 초고성능 차트 라이브러리)의 메인테이너인 leeoniya의 코멘트가 인상적이었습니다.

1. 픽셀 밀도 vs 데이터 밀도

가로 1,000픽셀짜리 차트에 100만 개의 점을 찍는 게 무슨 의미가 있을까요? 픽셀 하나당 1,000개의 데이터가 뭉개져서 표현됩니다. 이걸 그냥 그리면 Overplotting 문제가 발생하고, 안티앨리어싱 때문에 오히려 노이즈만 가득한 차트가 됩니다.

제대로 된 엔지니어링 접근이라면:

  • Downsampling (LTTB 등): 시각적으로 중요한 피크만 남기고 데이터를 줄여서 그리거나,
  • Density Map (Heatmap): 점들이 뭉친 곳을 색상의 강도로 표현해야 합니다.

ChartGPU는 기본적으로 샘플링을 수행하지만, 성능 벤치마크를 위해 이를 끌 수 있게 해 두었습니다. 하지만 실무에서는 100만 개를 ‘그냥’ 그리는 건 시각화 관점에서 무의미하다는 걸 기억해야 합니다.

2. 메모리 레이아웃의 아쉬움

현재 ChartGPU의 데이터 입력 포맷은 [[x, y], [x, y], ...] 형태의 Array of Arrays 입니다. 자바스크립트 엔진 내부적으로 이런 구조는 수백만 개의 작은 배열 객체를 생성하게 만들고, 이는 가비지 컬렉터(GC)에 엄청난 부하를 줍니다.

고성능을 지향한다면 Columnar Layout (즉, [x1, x2, ...], [y1, y2, ...])이나 TypedArray를 직접 받는 구조가 훨씬 유리합니다. GPU 버퍼로 데이터를 넘길 때도 직렬화 비용이 훨씬 줄어들죠. 이 부분은 차후 버전에서 반드시 개선되어야 할 병목 지점입니다.

AI가 짠 코드? (The Elephant in the Room)

저장소를 뜯어보다가 재미있는 점을 발견했습니다. .cursor/.claude/ 같은 폴더들이 포함되어 있더군요. HN 댓글에서도 지적되었듯, 이 프로젝트의 상당 부분이 AI 코딩 에이전트를 통해 작성되었을 가능성이 큽니다.

이게 나쁜 걸까요? 저는 그렇게 생각하지 않습니다. 결과물의 퀄리티가 중요하죠. 다만, 코드를 깊게 파다 보면 사람이 짰다면 하지 않았을 미묘한 패턴들이 보일 때가 있습니다. 예를 들어, 특정 엣지 케이스 처리가 누락되거나, 불필요하게 복잡한 추상화가 들어가는 식이죠.

실제로 HN 스레드 초기에 “가만히 있을 때도 CPU를 잡아먹는(Idle CPU usage)” 이슈가 보고되었습니다. 렌더 루프가 데이터 변경이 없어도 계속 돌고 있었던 거죠. 다행히 메인테이너가 피드백을 받고 즉시 수정했지만, 이런 디테일은 AI가 놓치기 쉬운 부분입니다.

결론: 아직은 ‘얼리 액세스’, 하지만 방향은 맞다

ChartGPU는 지금 당장 프로덕션 환경의 메인 차트 라이브러리로 쓰기에는 시기상조입니다.

  1. 브라우저 지원: WebGPU는 아직 모든 브라우저(특히 모바일과 파이어폭스)에서 완벽하지 않습니다.
  2. 기능 성숙도: D3나 ECharts가 가진 수만 가지의 커스터마이징 옵션에 비하면 아직 걸음마 단계입니다.
  3. 최적화: 앞서 언급한 데이터 구조나 메모리 관리 측면에서 더 다듬어야 할 부분이 많습니다.

하지만 방향성은 확실합니다. 데이터의 크기는 계속 커지고 있고, Canvas 2D API의 한계는 명확합니다. uPlot 같은 괴물 같은 최적화 라이브러리가 Canvas의 수명을 연장해주고 있지만, 결국 종착지는 GPU 컴퓨팅을 활용한 렌더링이 될 것입니다.

만약 사내 대시보드에서 수십만 건의 로그 데이터를 실시간으로 뿌려줘야 하는 상황이라면? 지금 당장 ChartGPU를 npm install 해서 테스트해볼 가치는 충분합니다. 단, 아직은 ‘베타 테스터’의 마음가짐으로 접근하시길 권합니다.

참고 링크: