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