[React] Virtual Scroll(가상 스크롤)로 렌더링 최적화하기 (react-window)

2025. 5. 5. 14:34·Library & Runtime/React

 

리스트가 길어질수록 모든 항목을 한 번에 렌더링하면 성능 문제가 발생한다.
특히 1,000개 이상의 데이터를 렌더링할 때 브라우저가 느려지고 사용자 경험이 저하된다.

이를 해결하는 기술이 Virtual Scroll(가상 스크롤)이다.

 

🔎 가상 스크롤(Virtual Scroll)이란?

가상 스크롤(Virtual Scroll)은 긴 리스트나 테이블에서 화면에 보이는 항목만 렌더링하고 나머지 항목은 렌더링하지 않는 기법이다.

  • 사용자가 스크롤할 때마다 보여줄 항목만 동적으로 추가한다.
  • 렌더링 비용과 메모리 사용량을 크게 줄일 수 있다.


항목 수가 많아도 초기 렌더링 속도를 빠르게 유지하고 스크롤 성능을 높이는 것이다.

💡 예: 카카오톡, 인스타그램, 유튜브 피드 → 수천~수만 개 항목이 있지만 느려지지 않는다.

 

🧩 예제 코드

import { FixedSizeList as List } from 'react-window';
import { useState } from 'react';

const ITEM_COUNT = 1000;

const generateItems = () => {
  return Array.from({ length: ITEM_COUNT }, (_, i) => `항목 ${i + 1}`);
};

const items = generateItems();

const Row = ({ index, style }: { index: number; style: React.CSSProperties }) => {
  console.log('렌더링된 항목:', index);
  return <div style={{ ...style, padding: 8, borderBottom: '1px solid #ddd' }}>{items[index]}</div>;
};

const ListCompare = () => {
  const [showNormalList, setShowNormalList] = useState(true);

  return (
    <div style={{ padding: 20 }}>
      <h2>Virtual Scroll 실험</h2>
      <button onClick={() => setShowNormalList(!showNormalList)}>
        {showNormalList ? 'Virtual Scroll 보기' : '일반 리스트 보기'}
      </button>

      <div style={{ marginTop: 20, height: 400, overflow: 'auto', border: '1px solid #ccc' }}>
        {showNormalList ? (
          <div>
            {items.map((_, index) => (
              <Row
                key={index}
                index={index}
                style={{ padding: 8, borderBottom: '1px solid #ddd' }}
              />
            ))}
          </div>
        ) : (
          <List height={400} itemCount={ITEM_COUNT} itemSize={35} width={'100%'}>
            {Row}
          </List>
        )}
      </div>
    </div>
  );
};

export default ListCompare;

총 1,000개의 항목 데이터를 생성하여 일반 리스트는 1,000개 항목을 모두 렌더링하고,  Virtual 리스트는 react-window 라이브러리의 FixedSizeList를 사용하여 보이는 항목만 렌더링하도록 하였다.

 

🧩 실험 결과

▶️ 일반 리스트

  • 1,000개의 항목이 모두 렌더링된다.
  • 브라우저의 메모리 사용량이 크게 증가한다.
  • 스크롤 성능이 느려진다.
  • 콘솔에 렌더링된 항목: 0 ~ 999가 한 번에 모두 출력된다.

 

▶️ Virtual 리스트

  • 보이는 영역에 해당하는 항목만 렌더링된다.
  • 스크롤할 때 새로운 항목만 추가 렌더링된다.
  • 브라우저 메모리 사용량이 일정하게 유지된다.
  • 콘솔에 스크롤 위치에 따라 일부 index만 출력된다.

React Developer Tools 익스텐션을 켜고 확인해 보면 스크롤할 때마다 렌더링되는 것을 확인할 수 있다.

 

📝 Virtual Scroll의 원리

  • 실제 DOM에는 화면에 보이는 항목만 추가된다.
  • 보이지 않는 항목은 렌더링하지 않고 스크롤 위치에 따라 동적으로 교체된다.
  • 렌더링 비용을 크게 줄여 긴 리스트에서도 빠른 반응성을 유지한다.

 

📝 정리

 

항목 일반 리스트 Virtual 리스트
렌더링 항목 수 전체 항목 (1,000개) 화면에 보이는 항목만
초기 렌더링 속도 느림 빠름
메모리 사용량 높음 낮음
스크롤 성능 느림 빠름

 

반응형

'Library & Runtime > React' 카테고리의 다른 글

[React] Control Props 패턴 : Controlled vs Uncontrolled  (0) 2025.05.07
[React] Compound Component 패턴 + Context 이해하기  (0) 2025.05.06
[React] 계산/렌더링 최적화: useMemo + React.memo 실험  (0) 2025.05.04
[React] 무거운 연산 최적화 : 일반 계산 vs useMemo  (0) 2025.05.03
'Library & Runtime/React' 카테고리의 다른 글
  • [React] Control Props 패턴 : Controlled vs Uncontrolled
  • [React] Compound Component 패턴 + Context 이해하기
  • [React] 계산/렌더링 최적화: useMemo + React.memo 실험
  • [React] 무거운 연산 최적화 : 일반 계산 vs useMemo
올콩
올콩
콩 심은 데 콩 난다
  • 올콩
    콩스토리
    올콩
  • 전체
    오늘
    어제
    • 분류 전체보기 (140)
      • SSAFY (10)
      • Algorithm (67)
        • 이론 (5)
        • 백준 (BOJ) (61)
        • 프로그래머스 (1)
      • Language (9)
        • JavaScript (0)
        • TypeScript (0)
        • Java (9)
        • Python (0)
      • Library & Runtime (15)
        • React (13)
        • Node.js (2)
      • Framework (9)
        • 이론 (2)
        • Next.js (3)
        • Vue (4)
      • DevOps (3)
        • Git (3)
      • WEB (17)
        • HTML (9)
        • error (6)
        • etc (2)
      • Computer (5)
        • 자격증 (2)
        • tip (2)
        • etc (1)
      • CS (5)
        • Network (1)
        • Blockchain (4)
  • 블로그 메뉴

    • GitHub
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    kakaomap
    딕셔너리
    해시
    오블완
    SSAFYcial
    html5
    dfs
    우선순위큐
    vue
    파이썬
    bfs
    Next.js
    백준
    DP
    Error
    강의
    React
    렌더링최적화
    블록체인
    자바
    Java
    알고리즘
    카카오맵
    SSAFY
    github
    Algorithm
    싸피
    소수
    티스토리챌린지
    재귀
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
올콩
[React] Virtual Scroll(가상 스크롤)로 렌더링 최적화하기 (react-window)
상단으로

티스토리툴바