Published on

자바스크립트 기반 차트 라이브러리 비교 (ApexCharts vs ECharts vs D3.js)

Authors

서론

프로젝트를 진행하면서 여러 차트 라이브러리를 사용해보았습니다. 프로젝트마다 명확한 기준 없이 라이브러리를 사용하다보니 각 차트 라이브러리의 특징을 정리해볼 필요성을 느꼈습니다.

특히 ApexCharts를 사용한 프로젝트에서 많은 양의 데이터를 렌더링할때 성능이 매우 느리는 문제가 있었습니다. 이후 ECharts로 변경 후 렌더링 성능이 개선되었지만 왜 이런 차이가 발생했는 지 궁금해졌습니다.

브라우저에 그림을 그리는 방법

차트를 그리는 방식은 크게 SVG 또는 Canvas 두 가지 방법이 있습니다.

차트 라이브러리 또한 이 두가지 방식 중 하나를 택하게 됩니다.


SVG와 Canvas 비교

canvas를 이용하여 그린 차트 GIF

자세한 내용은 SVG Vs. Canvas: A Comparison를 참고해주세요.

SVG (Scalable Vector Graphics):

  1. 도형과 DOM 통합: SVG는 HTML과 함께 DOM에 통합되어 있으며, CSS와 JavaScript를 통해 쉽게 스타일링하고 상호작용을 구현할 수 있습니다. 예를 들어, circle 요소에 클릭 이벤트를 추가하는 것은 HTML 요소에 이벤트를 추가하는 것과 동일하게 간단합니다.
  2. 해상도 독립적: SVG는 벡터 기반이므로 크기를 조정해도 품질이 유지됩니다. 따라서 다양한 해상도에서 선명한 이미지를 제공합니다. 주로 아이콘, 로고, 복잡한 도해, 및 반응형 웹 디자인에 적합합니다;.
  3. 접근성: SVG는 XML 기반으로, 스크린 리더와 같은 보조 기술에 의해 해석될 수 있어 접근성이 뛰어납니다. 또한 검색 엔진 최적화(SEO)에도 유리합니다.
  4. 애니메이션과 스타일링: SVG는 CSS를 통해 애니메이션과 스타일링이 가능합니다. 이를 통해 복잡한 애니메이션 효과를 구현할 수 있습니다.

Canvas:

  1. 픽셀 단위의 제어: Canvas는 픽셀 단위로 그래픽을 그리는 데 최적화되어 있으며, 고성능 애니메이션과 실시간 렌더링이 필요한 게임이나 인터랙티브 애플리케이션에 적합합니다. 직접 픽셀을 조작할 수 있어 복잡한 그래픽 처리에 강점이 있습니다.
  2. 고성능: 많은 객체를 빠르게 렌더링하는 데 유리합니다. 예를 들어, 수천 개의 객체를 포함하는 그래픽을 처리하는 경우 Canvas가 더 나은 성능을 발휘합니다.
  3. 복잡한 작업: 실시간 데이터 시각화, 예를 들어 주식 차트나 동적 대시보드 등의 복잡한 그래픽 작업에 유리합니다.
  4. 인터랙션 구현의 어려움: Canvas는 이벤트 리스너를 추가할 수 있지만, 이는 SVG보다 복잡합니다. Canvas는 기본적으로 단일 그래픽 영역이므로 특정 객체에 대한 상호작용을 구현하려면 추가적인 코딩이 필요합니다.

일반적으로 SVG는 해상도 독립적이고 접근성이 요구되는 그래픽 작업에 적합하며, Canvas는 고성능과 픽셀 단위의 세밀한 제어가 필요한 작업에 더 적합합니다. SVG는 복잡한 도해나 반응형 디자인에 유리하고, Canvas는 실시간 렌더링과 고성능 그래픽 작업에 유리합니다.


차트 라이브러리 비교

프로젝트를 진행하면서 사용했던 EChart, D3.js, ApexCharts를 비교해보았습니다.

각 공식문서에 있는 기본 예제 중 선형 차트를 기준으로 3000부터 190만까지 데이터를 처리하는 시간을 비교해보았습니다.

각각의 라이브러리의 선형 차트 비교
데이터 수 (개)EChart 렌더링 시간 (ms)D3.js 렌더링 시간 (ms)ApexCharts 렌더링 시간 (ms)
3,0001.323.29260.64
6,0003.245.12836.21
10,0004.757.91x
50,00022.4146.39x
100,00031.7681.11x
200,00066.67182.52x
500,000154.68483.51x
1,000,000326.78947.71x
1,900,000790.85xx

표를 살펴보면 데이터가 증가함에 따라 렌더링 시간도 증가하는 경향을 보입니다. D3.js의 경우는 190만개 이상의 데이터를 처리하지 못하고 ApexCharts는 7000개 이상의 데이터를 처리하지 못합니다.

왜 이런 차이가 발생한 것인지 개발자도구를 이용하여 각각의 차트가 어떻게 구성되어 있는지 확인해보았습니다.

canavs로 그린 EChart svg로 그린 D3.js svg로 그린 ApexCharts
차트 라이브러리렌더링 방식
EChartCanvas
D3.jsSVG
ApexChartsSVG

표에서 볼 수 있듯이, EChartCanvas를 사용하여 그래픽을 렌더링하고, D3.jsApexChartsSVG를 사용합니다.

CanvasSVG 보다 대용량 데이터를 처리하는데 유리하다는 것은 앞서 설명한 내용에서 확인할 수 있습니다.

그런데 같은 SVG를 사용하는 D3.jsApexCharts는 왜 이런 성능 차이가 발생한 것일까요?

개발자 도구를 이용하여 세부적으로 살펴보겠습니다.

D3.js 세부 코드 분석 ApexCharts 세부 코드 분석

D3.js는 svg 태그 안에 path 태그를 사용하여 선을 그리고, ApexChartsline 태그를 사용하여 선을 그립니다. 각각의 태그 사용에 따라 성능에 어떤 영향이 미치는지 자세히 알아보겠습니다.


Line 태그와 Path 태그 비교

line 태그

line 태그는 두 점을 연결하는 직선을 그립니다. 차트를 그릴 때 line 태그를 사용하면 각 데이터 포인트 사이에 선을 그릴 수 있습니다.

<svg width="500" height="500">
  <g id="line-chart">
    <line x1="10" y1="10" x2="50" y2="100" stroke="black"/>
    <line x1="50" y1="100" x2="90" y2="50" stroke="black"/>
    <!-- 더 많은 선들 -->
  </g>
</svg>

장점

  1. 단순하고 직관적입니다.
  2. 각 선을 개별적으로 스타일링하거나 이벤트를 추가하기 쉽습니다.

단점

  1. 많은 데이터를 처리할 때 태그의 수가 급격히 증가하여 DOM 트리가 커집니다.
  2. 복잡한 경로를 그리기 위해서는 많은 line 태그가 필요합니다.

path 태그

path 태그는 복잡한 도형을 그릴 수 있는 유연한 태그입니다. d 속성에 다양한 명령어를 사용해 경로를 정의합니다.

<svg width="500" height="500">
  <g id="path-chart">
    <path d="M10 10 L50 100 L90 50" stroke="black" fill="none"/>
    <!-- 더 많은 경로 -->
  </g>
</svg>

장점

  1. 복잡한 도형을 하나의 태그로 정의할 수 있어 코드가 간결해집니다.
  2. 데이터 포인트가 많아도 태그 수가 줄어들어 DOM 트리가 상대적으로 작아집니다.

단점

  1. 경로 명령어가 복잡할 수 있어 초기 러닝 커브가 있습니다.
  2. 경로의 일부를 개별적으로 스타일링하거나 이벤트를 추가하기 어렵습니다.

성능 비교

성능 측면에서 line 태그와 path 태그는 차트 데이터가 커질 때 명확한 차이가 있습니다.

  • DOM 크기 : line 태그를 사용할 경우 각 데이터 포인트 사이에 하나의 태그가 필요하므로 데이터가 많아질수록 DOM 트리가 커집니다. 반면, path 태그는 하나의 태그로 전체 경로를 정의할 수 있어 DOM 트리가 작아집니다.

  • 렌더링 성능 : 브라우저가 DOM 트리를 렌더링할 때, 많은 태그를 처리하는 것이 더 시간이 많이 걸립니다. 따라서 path 태그를 사용하는 것이 렌더링 성능에서 더 유리합니다.

  • 메모리 사용 : 많은 line 태그는 더 많은 메모리를 소비할 수 있습니다. path 태그는 메모리 사용량이 상대적으로 적습니다.


결론

이번 분석을 통해 ECharts, D3.js, ApexCharts 세 가지 차트 라이브러리의 성능 차이를 명확히 이해할 수 있었습니다. EChartsCanvas를 사용하여 대량의 데이터를 빠르게 처리하는 데 탁월한 성능을 보여주었으며, D3.jsApexChartsSVG를 사용함에도 불구하고 성능 차이가 있었습니다. 이는 D3.jspath 태그를 사용하여 더 효율적으로 DOM을 관리하고, ApexChartsline 태그를 사용하여 데이터 포인트가 많을 때 DOM의 크기가 커지는 것에서 기인합니다.

이러한 성능 차이는 각 라이브러리가 데이터를 어떻게 처리하고 DOM에 어떻게 표현하는지에 따라 달라집니다. 따라서 프로젝트의 요구 사항에 맞추어 적절한 차트 라이브러리를 선택하는 것이 중요합니다. 대용량 데이터를 빠르게 처리해야 하는 경우 ECharts의 사용을 고려할 수 있으며, 상호작용이 많고 세밀한 스타일링이 필요한 경우 D3.js를 고려할 수 있습니다.

이번 비교를 통해 각 라이브러리가 왜 특정 구현 방식을 선택했는지에 대한 깊은 이해를 얻을 수 있었으며, 이는 향후 비슷한 기술 선택에 있어서 매우 유용한 지침이 될 것입니다.