
시리즈 마지막 편입니다. 이번에는 코드 이야기가 아니라 프로젝트를 만들면서 느낀 점, 그리고 실제 프로덕션 트레이딩 플랫폼을 만든다면 어떤 점들을 더 고려해야 하는지 정리해봤습니다.
전체 소스코드는 GitHub에 공개되어 있습니다.
git clone https://github.com/kimkuns91/upbit-realtime-dashboard.git cd upbit-realtime-dashboard npm install && npm run dev
1. 왜 이 프로젝트를 만들었는가
평소에 궁금했던 게 있었습니다. 주식이든 코인이든, 트레이딩 화면을 보면 숫자가 쉴 새 없이 바뀝니다. 호가창, 체결 내역, 캔들 차트가 동시에 움직입니다. 이걸 프론트엔드에서 어떻게 처리하는 걸까?
React로 일반적인 CRUD 앱을 만들 때는 상태 관리가 크게 문제 되지 않습니다. 사용자가 버튼을 클릭하면 상태가 바뀌고, 화면이 업데이트됩니다. 하지만 초당 10~20회씩 외부에서 데이터가 밀려들어오는 환경은 완전히 다릅니다.
직접 부딪혀보고 싶었습니다. 그래서 업비트 Public API를 가지고 실시간 대시보드를 만들어봤습니다.
2. 만들면서 배운 것
React의 경계를 알게 되었습니다
React는 선언적 UI를 만드는 데 훌륭한 도구입니다. 하지만 모든 상황에 맞지는 않습니다. 호가창 벤치마크에서 useState로 처리했을 때 렌더링이 13,800회까지 올라간 걸 보고, React 렌더링 사이클의 비용을 체감했습니다.
중요한 건 "React가 느리다"가 아닙니다. 어디에 React를 쓰고 어디에 쓰지 않을지 판단하는 것이 핵심이었습니다. 사용자 인터랙션은 React가 잘 처리합니다. 고빈도 데이터 스트림은 React를 우회하는 게 맞습니다.
WebSocket은 생각보다 손이 많이 갑니다
new WebSocket(url) 한 줄로 연결은 됩니다. 하지만 실제로 쓸 만한 수준으로 만들려면 생각해야 할 게 많았습니다.
- 연결이 끊어지면 어떻게 할 것인가 (재연결 전략)
- 여러 컴포넌트가 같은 데이터를 필요로 하면 어떻게 공유할 것인가 (싱글톤)
- React lifecycle과 WebSocket lifecycle이 다른데 어떻게 맞출 것인가 (cleanup)
- 구독 종목이 바뀌면 기존 구독은 어떻게 정리할 것인가
연결 하나 만드는 건 쉽지만, 안정적으로 유지하는 건 다른 차원의 문제입니다.
브라우저가 생각보다 강력합니다
벤치마크를 돌려보면 FPS가 셋 다 120으로 나옵니다. 최적화를 안 해도 화면이 멈추지는 않습니다. 최신 브라우저 엔진과 하드웨어가 그만큼 발전했습니다.
그렇다고 최적화가 의미 없는 건 아닙니다. 렌더링 13,800회와 2회는 CPU 점유율에서 차이가 납니다. 노트북 배터리가 빨리 닳고, 팬이 돌아가기 시작합니다. 모바일 기기에서는 체감 차이가 더 큽니다.
3. 실제 트레이딩 플랫폼이라면
이 프로젝트는 Public API만 사용하는 읽기 전용 대시보드입니다. 실제 트레이딩 플랫폼을 만든다면 고려해야 할 것들이 훨씬 많습니다. 만들면서 "실전에서는 이렇게 하면 안 되겠다" 싶은 것들을 정리해봤습니다.
인증과 보안
이 프로젝트는 Public API라서 인증이 없습니다. 실제 매매 기능을 넣으려면 API 키 관리, JWT 토큰, 세션 관리가 필요합니다. WebSocket 연결에도 인증 토큰을 실어야 하고, 토큰이 만료되면 재인증 후 재연결하는 로직이 필요합니다.
특히 금융 데이터를 다루므로 XSS, CSRF 같은 기본적인 보안은 물론이고, API 키가 클라이언트에 노출되지 않도록 서버 사이드에서 중계하는 구조가 필수입니다.
주문 실행과 데이터 정합성
읽기 전용 대시보드에서는 데이터가 1~2초 지연돼도 크게 문제가 없습니다. 하지만 실제 매매에서는 이야기가 다릅니다.
- 호가창에 보이는 가격으로 주문을 넣었는데, 실제 체결가가 다르면 문제입니다
- 네트워크 지연으로 주문이 중복 전송되면 안 됩니다
- 주문 상태(대기 → 체결 → 취소)를 실시간으로 정확하게 반영해야 합니다
클라이언트에서 보여주는 가격과 서버에서 처리하는 가격 사이의 갭을 어떻게 관리할 것인지가 핵심입니다. Optimistic UI를 쓸 것인지, 서버 확인을 기다릴 것인지에 대한 판단도 필요합니다.
다중 종목과 멀티 커넥션
이 프로젝트는 한 번에 1개 종목만 봅니다. 실제 트레이딩 플랫폼에서는 관심 종목 여러 개를 동시에 모니터링합니다.
- 종목마다 WebSocket 연결을 따로 만들 것인지, 하나의 연결에서 멀티플렉싱할 것인지
- 구독 종목이 50개, 100개가 되면 데이터 처리량을 어떻게 감당할 것인지
- 필요 없는 종목은 자동으로 구독 해제하는 GC 로직이 필요합니다
업비트 WebSocket은 하나의 연결에서 여러 종목을 구독할 수 있지만, 종목이 많아지면 메시지 처리량이 기하급수적으로 늘어납니다. Web Worker로 파싱을 분리하는 것도 고려해야 합니다.
에러 처리와 모니터링
이 프로젝트에서는 에러가 나면 콘솔에 찍히는 게 전부입니다. 프로덕션에서는 그렇게 할 수 없습니다.
- WebSocket 연결 실패, 파싱 에러, API 응답 이상 등을 구분해서 처리해야 합니다
- 사용자에게 "현재 데이터가 지연되고 있습니다" 같은 안내를 보여야 합니다
- Sentry 같은 에러 트래킹 도구로 문제를 수집하고 분석해야 합니다
- 데이터가 일정 시간 안 들어오면 stale 상태로 표시하는 로직도 필요합니다
금융 서비스에서 "조용히 실패하는 것"은 가장 위험한 버그입니다.
테스트
이 프로젝트에는 테스트 코드가 없습니다. 연습용이니까 넘어갔지만, 프로덕션에서는 그럴 수 없습니다.
- WebSocket 메시지 파싱 로직은 단위 테스트가 필수입니다
- 재연결, 구독 변경 같은 시나리오는 통합 테스트가 필요합니다
- 캔들 차트의 시간 범위 계산이 틀리면 잘못된 차트가 그려집니다
- 호가창 정렬이 잘못되면 매수/매도가 뒤바뀝니다
특히 금융 데이터 처리에서 off-by-one 에러는 치명적입니다. 타임스탬프 계산, 가격 반올림, 수량 합산 같은 부분은 꼼꼼한 테스트가 필요합니다.
접근성과 국제화
트레이딩 플랫폼은 긴 시간 동안 화면을 응시하는 특성이 있습니다.
- 다크 모드뿐 아니라 고대비 모드도 고려해야 합니다
- 색각 이상이 있는 사용자를 위해 빨강/파랑 외에 다른 시각적 구분 수단이 필요합니다
- 스크린 리더가 가격 변동을 읽어줄 수 있어야 합니다
- 키보드만으로 주문을 넣을 수 있어야 합니다
국제화도 중요합니다. 가격 포맷(소수점 vs 쉼표), 시간대, 통화 단위가 사용자마다 다릅니다.
4. 기술 선택을 다시 한다면
프로젝트를 처음부터 다시 만든다면 몇 가지 다르게 할 것 같습니다.
Web Worker 도입: WebSocket 메시지 파싱을 메인 스레드에서 분리하면 UI가 더 부드러워집니다. 특히 다중 종목을 처리할 때 효과가 클 것 같습니다.
SharedArrayBuffer 검토: 고빈도 데이터를 Worker와 메인 스레드 사이에서 효율적으로 공유하는 방법입니다. 다만 보안 헤더(COOP, COEP) 설정이 필요해서 배포 환경에 따라 제약이 있습니다.
Canvas 기반 호가창: DOM 조작 대신 Canvas로 호가창을 그리면 렌더링 비용을 더 줄일 수 있습니다. TradingView 같은 전문 플랫폼이 차트를 Canvas로 그리는 이유가 있습니다.
5. 시리즈를 마치며
3편의 기술 글과 이번 회고까지, 실시간 트레이딩 대시보드를 만드는 과정을 기록해봤습니다.
- [01] WebSocket 파이프라인 — 싱글톤 매니저, Blob 파싱, 재연결 전략
- [02] 캔들 차트 — TradingView Lightweight Charts, REST + WS 조합
- [03] 호가창 최적화 — useState → throttle → useRef+rAF, 렌더링 6,900배 차이
- [04] 회고 — 배운 것과 실전과의 거리
이 프로젝트는 "고빈도 실시간 데이터를 프론트엔드에서 어떻게 처리하는가"에 대한 연습이었습니다. 실제 프로덕션과는 거리가 있지만, 핵심 패턴을 직접 구현해보면서 감을 잡을 수 있었습니다.
가장 큰 교훈은 하나입니다. 도구의 한계를 알아야 도구를 제대로 쓸 수 있습니다. React가 만능이 아니라는 걸 알아야, 적절한 지점에서 React를 우회하는 판단을 내릴 수 있습니다.
전체 소스코드는 GitHub에 공개되어 있습니다.
'Frontend Development > [실습] 실시간 트레이딩 대시보드 만들기' 카테고리의 다른 글
| [실시간 트레이딩 대시보드 만들기 - 03] 초당 20회 업데이트되는 호가창, 렌더링 횟수를 6,900배 줄인 방법 (0) | 2026.02.12 |
|---|---|
| [실시간 트레이딩 대시보드 만들기 - 02] TradingView Charts로 실시간 캔들 차트 구현 (0) | 2026.02.12 |
| [실시간 트레이딩 대시보드 만들기 - 01] WebSocket 파이프라인 설계와 Blob 파싱 (0) | 2026.02.12 |
