프로젝트/정글 FE 스터디

[React] Lazy Loading과 코드 스플리팅

KimCookieYa 2023. 8. 30. 02:01

Lazy Loading

React에서 Lazy Loading은 주로 Code Splitting을 위해 사용되는 기법이다. 이 기법을 통해 애플리케이션의 초기 로딩 시간을 줄이고, 성능을 향상시킬 수 있다.

 

Lazy Loading의 주요 목표

특정 컴포넌트 또는 모듈을 실제로 필요할 때까지 로딩하지 않는 것

이렇게 함으로써 초기 페이지 로드에 필요한 코드 양을 불이고, 초기 로딩 성능을 개선할 수 있다. React 16.6 버전부터 React.lazy()Suspense를 사용하여 Lazy Loading을 쉽게 구현할 수 있게 되었다.

 

사용 방법

  1. React.lazy(): 컴포넌트 외부에서 동적 import() 문법을 사용하여 컴포넌트를 로드하는 함수를 받아, 자동으로 컴포넌트를 Lazy Load한다.
    const LazyComponent = React.lazy(() => import('./LazyComponent'));
  2. Suspense: Lazy 컴포넌트의 로딩 동안 보여줄 Fallback 컴포넌트나 로딩 표시를 설정할 수 있다.
import React, { Suspense } from 'react';
function App() {
    return (
        <div>
            <Suspense fallback={
                <div>Loading...</div>
            }>
                <LazyComponent />
            </Suspense>
        </div>
    );
}

 

Troubleshooting

  • lazy 컴포넌트의 상태가 예기치 않게 초기화된다.
    => 다른 컴포넌트 안에서 lazy 컴포넌트를 선언하지 마라. 대신 항상 모듈의 최상위 레벨에서 선언하자.
import { lazy } from 'react';

// ✅ Good: Declare lazy components outside of your components  
// ✅ 좋음: lazy 컴포넌트를 컴포넌트들의 밖에서 선언하세요  
const MarkdownPreview = lazy(() => import('./MarkdownPreview.js'));

function Editor() {
  // 🔴 Bad: This will cause all state to be reset on re-renders
  // 🔴 나쁨: 이렇게 하면 리렌더링시마다 모든 state가 초기화됩니다
  const MarkdownPreview = lazy(() => import('./MarkdownPreview.js'));
  // ...
}

 

exports

동적 import 함수는 default export(기본 내보내기)된 컴포넌트를 import 한다. 그래서 named export된 컴포넌트는 다른 방법을 사용해야 한다.

import { lazy } from 'react';

const SomeComponent = lazy(() =>
    import('./SomeModule.js').then(module => ({
        default: module.SomeComponent,
    })),
)

 

코드 스플리팅

React에서 코드 스플리팅의 필요성은 다음과 같다.

  1. 초기 로드 시간 감소
    • 웹 애플리케이션의 번들 크기가 크면 초기 로드 시간이 길어져 사용자 경험(UX) 저하된다.
    • Lazy Loading을 통해 초기에 로딩되는 번들의 크기를 줄일 수 있다.
    • 따라서 사용자가 실제로 방문하지 않는 페이지나 컴포넌트의 코드를 불러오지 않게 함으로써 초기 로드 시간을 단축시킬 수 있다.
  2. 효율적인 네트워크 및 메모리 사용
    • 모든 코드를 미리 로드하면 불필요한 네트워크 대역폭과 메모리가 사용된다.
    • Lazy Loading은 사용자가 실제로 필요로 하는 부분만 로드하기 때문에, 불필요한 리소스 사용을 피하고 애플리케이션의 효용성을 높일 수 있다.
  3. 사용자 경험(UX) 향상
    • 사용자는 빠른 웹 사이트를 선호한다.
    • 코드 스플리팅을 통해 필요한 리소스만 로드하므로 페이지의 반응성이 향상되고 사용자 경험(UX)이 개선된다.

 

제한사항

  • Pre-Fetching과의 균형: 너무 많은 코드 스플리팅을 하면 네트워크 요청의 수가 많아질 수 있다. 때로는 프리패칭을 사용하여 사용자의 다음 동작을 예측하고 미리 필요한 코드를 로드하는 것이 좋을 수 있다.
  • Flash of Content 현상: Lazy Loading이 너무 늦게 발생하면 사용자가 일시적으로 빈 화면을 보게 될 수 있다. 이를 방지하기 위해 스켈레톤 스크린이나 Suspence를 사용한 로딩 플레이스홀더를 사용하는 것이 좋다.

 

출처