Javascript

JavaScript로 2000건 이상의 데이터를 그리드로 표시할 때 속도 개선 방법

지오준 2024. 12. 2. 10:00
반응형

대량의 데이터를 JavaScript 기반의 그리드 컴포넌트에 표시하면 성능 문제가 발생할 수 있습니다. 브라우저가 많은 DOM 요소를 렌더링하고 관리하는 데 부담을 느끼기 때문입니다. 이런 상황에서 효율적인 데이터 렌더링 및 관리 기술을 사용하면 화면 속도를 크게 개선할 수 있습니다. 아래는 다양한 최적화 방법과 샘플 코드입니다.

---

#### 1. **가상 스크롤(Virtual Scrolling)**

가상 스크롤은 사용자가 보이는 범위 내에서만 DOM 요소를 렌더링하고, 나머지 데이터는 메모리로 관리하는 기법입니다. 이렇게 하면 DOM에 불필요한 요소를 렌더링하지 않아 성능을 개선할 수 있습니다.

##### 주요 구현 방법:
1. **데이터 청크 분리**: 화면에 보이는 데이터만 선택하여 렌더링.
2. **스크롤 이벤트 처리**: 스크롤 위치에 따라 동적으로 데이터 업데이트.

##### 예제 코드:
```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Virtual Scrolling</title>
  <style>
    #grid {
      height: 400px;
      overflow-y: auto;
      border: 1px solid #ccc;
    }
    .row {
      height: 40px;
      display: flex;
      align-items: center;
      border-bottom: 1px solid #eee;
    }
  </style>
</head>
<body>
  <div id="grid"></div>
  <script>
    const totalRows = 2000; // 총 데이터 수
    const rowHeight = 40; // 각 행의 높이
    const visibleRows = 10; // 한 번에 보이는 행 수
    const buffer = 5; // 추가로 렌더링할 행 수 (스크롤 안정성)

    const grid = document.getElementById('grid');
    grid.style.height = `${rowHeight * visibleRows}px`;

    const content = document.createElement('div');
    content.style.height = `${rowHeight * totalRows}px`;
    grid.appendChild(content);

    const renderRows = (start) => {
      const end = Math.min(start + visibleRows + buffer, totalRows);
      content.innerHTML = ''; // 기존 렌더링 데이터 초기화
      for (let i = start; i < end; i++) {
        const row = document.createElement('div');
        row.className = 'row';
        row.textContent = `Row ${i + 1}`;
        row.style.transform = `translateY(${i * rowHeight}px)`;
        content.appendChild(row);
      }
    };

    let lastScrollTop = 0;
    grid.addEventListener('scroll', () => {
      const scrollTop = grid.scrollTop;
      const start = Math.floor(scrollTop / rowHeight);
      if (start !== lastScrollTop) {
        renderRows(start);
        lastScrollTop = start;
      }
    });

    // 초기 렌더링
    renderRows(0);
  </script>
</body>
</html>
```

---

#### 2. **페이지네이션(Pagination)**

페이지네이션은 한 번에 일부 데이터만 가져와 화면에 표시하는 방식입니다. 사용자가 다음 페이지로 이동할 때마다 새 데이터를 가져옵니다.

##### 주요 구현 방법:
1. 데이터베이스에서 필요한 데이터만 가져오기.
2. 클라이언트에서 페이지 데이터를 캐싱하여 요청 수 줄이기.

##### 예제 코드:
```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Pagination</title>
</head>
<body>
  <div id="grid"></div>
  <button id="prev">Previous</button>
  <button id="next">Next</button>

  <script>
    const grid = document.getElementById('grid');
    const pageSize = 100; // 페이지당 데이터 수
    let currentPage = 1;

    const fetchData = async (page) => {
      // 실제 API 호출 대신 샘플 데이터 생성
      return Array.from({ length: pageSize }, (_, i) => `Row ${(page - 1) * pageSize + i + 1}`);
    };

    const renderGrid = (data) => {
      grid.innerHTML = '';
      data.forEach(item => {
        const row = document.createElement('div');
        row.textContent = item;
        grid.appendChild(row);
      });
    };

    const updateGrid = async (page) => {
      const data = await fetchData(page);
      renderGrid(data);
    };

    document.getElementById('prev').addEventListener('click', () => {
      if (currentPage > 1) {
        currentPage--;
        updateGrid(currentPage);
      }
    });

    document.getElementById('next').addEventListener('click', () => {
      currentPage++;
      updateGrid(currentPage);
    });

    // 초기 데이터 로드
    updateGrid(currentPage);
  </script>
</body>
</html>
```

---

#### 3. **최적화된 그리드 라이브러리 사용**

직접 구현이 복잡하거나 시간이 부족한 경우, 성능에 최적화된 그리드 라이브러리를 사용하는 것도 좋은 방법입니다. 다음은 인기 있는 라이브러리들입니다:
- **AG Grid**: 기능이 풍부하고 성능 최적화가 잘 되어 있음.
- **Handsontable**: 엑셀과 유사한 인터페이스 제공.
- **React Table**: React 환경에 최적화된 테이블 라이브러리.

---

### 결론

2000건 이상의 데이터를 그리드에 표시할 때는 **가상 스크롤**과 **페이지네이션**이 가장 효과적인 방법입니다. 경우에 따라 최적화된 라이브러리를 사용하는 것도 유용합니다. 위의 방법들을 프로젝트 요구사항에 맞게 적용하여 성능 문제를 해결하세요!

반응형