React Gantt 차트 라이브러리 벤치마크 — 6개 직접 비교
Gantt 차트 라이브러리 선택은 생각보다 까다롭다. 무료인 줄 알았는데 기능 제한이 있거나, 화면에서는 예쁜데 데이터 10만 건 넣으면 브라우저가 죽는다.
SVAR가 6개 React Gantt 라이브러리를 1,000개부터 100,000개까지 데이터셋을 올려가며 직접 벤치마크했다. 결과가 꽤 극적이다.
한 줄 결론
- 자주 업데이트되는 대규모 데이터 → SVAR React Gantt
- 정적 렌더링, 부드러운 스크롤 우선 → DHTMLX 또는 Bryntum
- 엔터프라이즈 지원 필요 → Syncfusion (단, 대규모 데이터 주의)
- Kendo/DevExtreme는 신규 프로젝트에 비추천 — 이유는 아래에
비교 대상
| 라이브러리 | 아키텍처 | 라이선스 |
|---|---|---|
| SVAR React Gantt | React 네이티브 | 유료 |
| DHTMLX | Vanilla JS 래핑 | 유료 |
| Bryntum | Vanilla JS 래핑 | 유료 |
| Syncfusion | 클로즈드 소스 | 유료 |
| DevExtreme | 클로즈드 소스 | 유료 |
| KendoReact | Pure React | 유료 |
모두 유료다. 무료 오픈소스 Gantt 라이브러리가 프로덕션 수준에서 한계가 있는 이유가 있다.
[💡 잠깐! 이 용어는?] Vanilla JS 래핑: 순수 JavaScript로 만든 라이브러리를 React에서 쓸 수 있도록 얇게 감싼 것. React의 가상 DOM 이점을 못 살리는 경우가 많다.
벤치마크 방법론
5가지 카테고리, 데이터셋 규모는 1,000 / 10,000 / 100,000 태스크.
- 로딩 속도: 가상 스크롤 활성화 상태에서 초기 렌더링 시간
- 스크롤 성능: 연속 스크롤 중 초당 프레임(FPS)
- CRUD 작업: create/update/delete 100회 혼합 실행 시간
- 실시간 업데이트: 연속 데이터 변경 수신 중 FPS
- 메모리 사용량: 각 데이터셋 규모에서 RAM 소비
"정확한 밀리초는 브라우저, 하드웨어, OS에 따라 다르지만, 상대적인 성능 비율은 일관적이었다."
결과
로딩 속도
| 라이브러리 | 100k 태스크 로딩 |
|---|---|
| SVAR | 1.7초 |
| DHTMLX | 27초 |
| Bryntum | 34초 |
| Kendo | 4초 (1k에서도) |
| Syncfusion | 측정 불가 (크래시) |
SVAR가 압도적이다. DHTMLX와 16배 차이.
스크롤 성능
여기서 역전이 일어난다.
| 라이브러리 | 100k 스크롤 FPS |
|---|---|
| DHTMLX / Bryntum | 60 FPS |
| SVAR | 5 FPS |
Vanilla JS 래핑 라이브러리가 스크롤에서는 앞선다. React 네이티브 아키텍처의 트레이드오프다. 대규모 정적 데이터를 부드럽게 스크롤하려면 React의 재렌더링 사이클이 오히려 방해가 된다.
CRUD 작업
| 라이브러리 | 100k 기준 100회 CRUD |
|---|---|
| SVAR | 1.1초 |
| DHTMLX (배치) | 12초 |
| DevExtreme | 33초 (재앙) |
DevExtreme는 기본 CRUD 작업에 33초. 실시간 업데이트가 필요한 앱이라면 사용 불가 수준이다.
메모리
| 라이브러리 | 100k 메모리 |
|---|---|
| DHTMLX | 88 MB |
| SVAR | 380 MB |
| Bryntum | 1.8 GB |
Bryntum은 50,000 행에서 1.8 GB를 쓴다. 브라우저 탭이 죽을 수 있는 수준이다.
아키텍처가 성능을 결정한다
결과에서 패턴이 보인다. React 네이티브 라이브러리(SVAR)는 데이터 업데이트에 강하다. React의 상태 관리와 자연스럽게 통합되기 때문이다. 반면 Vanilla JS 래퍼(DHTMLX, Bryntum)는 DOM 직접 조작으로 스크롤이 부드럽다.
프로젝트 특성에 따라 선택이 달라진다.
선택 체크리스트
SVAR React Gantt 선택 시:
- 데이터가 자주 업데이트되는가
- React 상태 관리와 깊이 통합해야 하는가
- 초기 로딩 속도가 스크롤 부드러움보다 중요한가
DHTMLX 선택 시:
- 데이터가 주로 정적이고 조회가 많은가
- 사용자가 대량 데이터를 스크롤하는 시나리오가 많은가
- 메모리 효율이 중요한가
피해야 할 케이스:
- DevExtreme: CRUD 성능 문제로 실시간 업데이트 시나리오 부적합
- Bryntum: 50k+ 행에서 메모리 문제
- Syncfusion: 대규모 데이터에서 크래시
벤치마크의 한계
한 가지 중요한 점이 있다. 이 벤치마크에서 테스트하지 않은 것이 있다 — 스케줄링 로직. Gantt 차트의 핵심 기능 중 하나인 의존성 자동 해결, 제약 조건 관리 같은 기능은 측정 대상이 아니었다. 프로덕션에서 중요하다면 별도로 평가해야 한다.
마무리
Gantt 라이브러리 선택은 결국 데이터가 얼마나 자주 바뀌는가에 달려 있다. 프로젝트 계획 도구처럼 정적 데이터가 많으면 DHTMLX가 낫고, 리소스 스케줄링처럼 실시간 업데이트가 많으면 SVAR가 낫다. 벤치마크를 보고 결정하되, 반드시 자기 데이터로 직접 확인해봐라.
참고:
- 원문: https://svar.dev/blog/react-gantt-benchmark/
- SVAR React Gantt: https://github.com/svar-widgets/gantt
관심 있을 만한 포스트
HTML Minifier 벤치마크 — 48개 사이트에서 어떤 도구가 이겼나
minify-html, htmlnano, HTML Minifier Next, @swc/html 등 주요 HTML 압축 도구를 실제 사이트로 비교한 벤치마크 결과와 선택 기준을 정리한다.
React Compiler의 한계 — 뭘 최적화하고 뭘 못 하는가
React Compiler가 자동 메모이제이션으로 해결하는 것과 해결하지 못하는 것. 컴파일러 기반 UI 프레임워크의 능력 경계를 정리했다.
JavaScript 이미지 프리로딩 — 5가지 방법 비교
new Image, link preload, hidden div, Cache API, fetch — 각 프리로딩 방식의 장단점과 상황별 선택 기준을 정리한다.
React 상태 올리기 — 대부분의 경우 하지 않는 게 낫다
React에서 습관적으로 lift state up을 하는 안티패턴을 살펴보고, 상태를 쓰는 곳 가까이 두는 편이 왜 더 나은지 정리한다.
Angular 1에서 React로 — Strangler 패턴으로 1년간 점진적 마이그레이션한 이야기
대규모 티켓 플랫폼을 Angular 1에서 React로 마이그레이션하면서 적용한 Strangler 패턴과 7가지 교훈을 정리한다.
Tsonic — TypeScript를 네이티브 바이너리로 컴파일하는 실험
TypeScript → C# → NativeAOT 파이프라인으로 네이티브 실행 파일을 만드는 Tsonic. 어떻게 동작하고, 어떤 한계가 있는지 살펴봤다.
Bun이 빠른 건 맞다 — 그런데 당신의 이벤트 루프가 문제다
Bun으로 바꿔도 p99가 개선되지 않는 이유. 런타임 선택보다 먼저 봐야 할 진짜 병목 지점들.
Coaction v1.0 — Web Worker로 멀티스레딩 상태 관리하기
JavaScript 단일 스레드 한계를 극복하는 상태 관리 라이브러리 Coaction의 동작 방식, Zustand와의 차이, Standard/Shared 두 가지 모드 사용법을 정리한다.