가상화
comins-table@0.2.2
virtualized prop은 대용량 row 표시를 위한 window rendering 경로를 사용합니다. 현재 gate는 100000 rows smoke와 perf 검증을 포함합니다. Header와 Body는 모든 모드에서 별도 table 태그로 렌더링합니다. Body viewport는 vertical scroll과 virtual range 갱신을 소유하고, horizontal overflow는 전체 Table 최하단의 scrollbar 하나가 Header, Body와 Summary를 동기화합니다. Header는 virtual body scroll 중에도 같은 위치에 유지됩니다.
기존 CSR 배열과 Viewport Datasource의 구간 조회를 지원합니다.
하단 도달 시 다음 batch를 외부에서 append하는 UX는 infiniteScroll, hasMoreRows, loadingMore, onLoadMore 또는 append-mode lazyLoad, onLazyLoad로 제어합니다.
100000 rows 검증은 Chrome DevTools Performance Monitor 기준으로 JS heap, DOM Node, JS event listener 증가가 스크롤 후 안정적으로 회수되는지 확인합니다. 문서 예제의 목적은 브라우저에 100000개 Row를 모두 DOM으로 그리지 않고, viewport 근처 Row만 유지하는 계약을 설명하는 것입니다. 수동 성능 검증에서는 GC 이후 값을 기준으로 비교하고, 기본 예제 페이지로 이동했을 때 DOM Node와 listener 수가 비정상적으로 남지 않는지 확인합니다.
const data: Row[] = Array.from({ length: 100000 }, (_value, index) => ({ id: `row-${index}`, name: `Row ${index}`,}));
<CominsTable columns={[{ field: "name", label: "Name" }]} data={data} getRowId={(row) => row.id} buffer-size={10} pagination={{ pageIndex: 0, pageSize: data.length }} rowHeight={32} virtualized/>"buffer-size"는 virtualized body가 viewport 위/아래에 추가로 유지하는 row buffer 크기입니다. 기본값은 10이며, 컴포넌트 Cell이나 custom renderer처럼 Cell 렌더 비용이 큰 테이블에서 불필요한 pre-render 비용을 줄이는 방향으로 맞춰져 있습니다. 빠른 스크롤에서 blank 구간을 줄여야 하는 경우 10~20 수준에서 먼저 조정하고, buffer를 크게 잡을수록 동시에 유지되는 DOM Node와 Cell 렌더 비용이 증가합니다. 논리 높이가 매우 큰 경우 body scroll height는 브라우저 한계를 피하도록 bounded coordinate로 보정됩니다.
rowHeight는 virtualized range, scroll height, render offset 계산의 기준값입니다. Theme CSS에서 tr 또는 td 높이를 override할 수는 있지만, virtualized table에서는 visual height만 CSS로 바꾸면 scroll 위치와 실제 row 높이가 어긋날 수 있습니다. 같은 고정 행 높이를 바꾸는 경우 rowHeight prop과 --comins-table-row-height, --comins-table-cell-height 값을 같은 숫자로 맞춥니다.
같은 고정 높이의 Row는 기존 산술 경로를 유지합니다. Row별 높이·자동 높이·펼쳐진 Detail은 private height index를 사용합니다. 자동 높이를 참고합니다.
data는 immutable input으로 취급합니다. Row 값을 수정할 때는 기존 배열을 직접 mutate하지 않고 새 배열 참조로 교체합니다. 현재 client-side data 배열 계약에서는 row 객체와 row id 파생 데이터가 row 수에 비례해 browser memory를 사용합니다. 필요한 구간만 외부에서 공급하려면 Viewport Datasource를 사용합니다.
대용량 데이터에서 이벤트 payload는 전체 state metadata를 포함하지 않고 필요한 row, column, value만 전달합니다.
Manual Performance Checklist
섹션 제목: “Manual Performance Checklist”- Chrome DevTools Performance Monitor를 열고 GC 이후 JS heap, DOM Node, JS event listener 값을 기록합니다.
- 100000 rows 예제에서 마우스 휠 스크롤과 scrollbar drag를 모두 수행합니다.
- 스크롤 후 기본 예제 페이지로 이동하고 GC 이후 DOM Node와 listener가 10% 이내 수준으로 회수되는지 확인합니다.
- 같은 고정 높이의 가상화에서는
rowHeight와--comins-table-row-height,--comins-table-cell-height값이 불일치하면 virtual range 계산과 실제 row 높이가 어긋날 수 있으므로 같은 숫자로 맞춥니다.
Column Filtering은 virtual range 계산 전에 source index를 파생합니다. 따라서 Filter 변경은 logical projection을 갱신하지만 application은 변경되지 않은 전체 data 배열과 stable Row ID를 계속 소유합니다.
데이터 조회 방식 선택
섹션 제목: “데이터 조회 방식 선택”| 방식 | 애플리케이션이 보유하는 데이터 | 스크롤 동작 |
|---|---|---|
배열 + virtualized |
전체 Row 배열 | 현재 화면과 buffer만 DOM에 렌더링 |
| Infinite Scroll / Lazy Load | 요청할 때마다 누적한 Row | 앞선 batch부터 순차 조회하여 다음 구간에 접근 |
| Viewport Datasource | useCominsViewport로 관리하는 제한된 block |
알려진 전체 건수를 기준으로 임의 구간 조회 |
자동 높이는 가상화 및 Viewport 조회와 결합할 수 있습니다. 마운트된 콘텐츠를 측정하고 알 수 없는 높이는 추정하며 전체 데이터를 미리 측정하지 않습니다. Row 자동 높이와 Viewport Datasource를 참고합니다.