그럼에도 불구하고

👨‍💻

[React] 레이지 로딩이란? 본문

React/React basics

[React] 레이지 로딩이란?

zenghyun 2023. 7. 8. 01:15

레이지 로딩에 대해 알아보겠습니다. :) 

 

목차

     

    [ 레이지 로딩 (Lazy Loading) ]

    SPA (Single Page Application)은 파일 하나와 다수의 자바스크립트 코드 그리고 CSS 파일로 구성됩니다. 이런 구성 때문에 SPA에는 약간의 문제점이 있습니다.

     

    리액트 라우터를 적용한 수백에서 수천 개의 화면과 컴포넌트로 구성된 애플리케이션이 있다고 가정해 봅시다.

     

    수백, 수천 개의 컴포넌트를 작성할 때 만들어진 자바스크립트 파일은 모두 빌드 과정을 거쳐서 하나 또는 몇 개의. js 파일로 빌드됩니다.

    빌드된 파일은 모든 컴포넌트를 묶은 것이므로 파일의 크기도 클 것으로 예상할 수 있습니다.

     

    브라우저는 첫 화면을 로딩하기 위해 브라우저가 웹 서버에 경로를 요청하면, 웹 서버는 하나의. js파일을 브라우저에 넘기게 되고. 이를 받은 브라우저는 모든 화면을 위한. js 파일을 로딩합니다.

     

    이때 지연 시간이 발생해서 사용자는 첫 화면을 보기까지 기다리는 시간이 길어질 수 있습니다.

     

    이 문제를 해결하는 방법 중 하나가 레이지 로딩 (lazy loading) 기법입니다.

     

    레이지 로딩은 리액트 애플리케이션의 수많은 화면과 컴포넌트 코드를 적절히 구분하여 화면, 컴포넌트 그룹 단위로 여러 개의 청크(chunk)라 부르는. js 파일로 빌드하고 특정 컴포넌트가 필요한 시점에 서버에 요청해서 청크 파일을 응답받아 렌더링 하는 방법입니다.

     

    https://mari-mo.tistory.com/206

     

    위의 그림 같이 레이지 로딩을 사용하면, 사용자가 필요한 화면과 컴포넌트 코드만 가져오며, 나머지 화면과 코드는 대기 상태로 들어가게 됩니다. 

     

    즉, 레이지 로딩 기법의 핵심은 특정 화면이 필요할 때 관련된 컴포넌트를 포함하고 있는. js 파일을 웹 서버에 요청하여 받아오는 것입니다.

     

    이 방법을 사용하면 애플리케이션이 수많은 컴포넌트를 포함하더라도 첫 화면을 요청할 때는 작은 크기의 청크 파일을 요청하고 응답받으므로 사용자에게 첫 화면을 더 신속하게 보여줄 수 있습니다.

     

     

    [ 레이지 로딩 적용 방법 ]

    레이지 로딩을 적용하려면 컴포넌트의 임포트를 필요한 시점에 비동기로 수행할 수 있어야 합니다. 

    이를 위해서 React.lazy() 함수와 import 함수를 이용합니다.

     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    // 기존의 정적 import 방법
    import Home from './Home' // 1번
     
    // React.lazy()와 import 함수 사용
    const Home = React.lazy(() => import("./Home")); // 2번
     
    // webpackChunkName 지정, 3번
    const Home = React.lazy(() => import(/* webpackChunkName:"home" */ "./Home")); 
    const Blog = React.lazy(() => import(/* webpackChunkName:"home" */ "./Blog")); 
    cs

     

    위 예시에서 1번 코드는 기존의 정적으로 필요한 컴포넌트를 임포트 하는 방법입니다. 레이지 로딩을 적용하려면 2번과 같은 형태로 컴포넌트를 임포트해야 합니다. 애플리케이션을 실행할 때 Home 컴포넌트가 필요한 시점이 되면 React.lazy()에 등록된 함수가 실행되면서 비동기로 컴포넌트를 임포트해옵니다.

     

    3번의 webpackChunkName 주석은 이름이 같은 것 끼리 모아서 청크 파일을 생성하며, 생성된 청크 파일의 이름은 home.f4c1 eac.js와 유사한 형태입니다. webpackChunkName은 함께 사용되는 컴포넌트를 모아서 하나의 청크로 생성해 주는 고마운 기능입니다. 

     

    참고로 이 기능은 코드를 여러 개의 조각으로 분할해 준다고 해서 코드 스플리팅 (code splitting)이라고도 부릅니다.

     

     

    📌 webpackChunkName을 사용하려면 알아둬야 할 사항

    webpackChunkName은 이름에서 알 수 있듯이 webpack이라는 빌드 시스템이 지원하는 기능입니다.

    CRA(create-react-app) 도구를 이용해 리액트 프로젝트를 생성했다면 webpack이 기본으로 지원되므로 별도의 설정 없이 webpackChunkName 기능을 사용할 수 있지만,

     

    만약  Vite로 생성된 프로젝트인 경우 별도의 설정이 필요합니다. 

     

    설정 방법은 다음과 같습니다.

     

    1. Vite에서 사용할 수 있도록 다음 명령어를 이용해 webpackChunkName 플러그인을 설치합니다.

    npm install -D vite-plugin-webpackchunkname 
    
    yarn add -D vite-plugin-webpackchunkname

     

    2.  vite.config.js에 다음과 같은 vite-plugin-webpackchunkname 플러그인의 설정을 추가합니다.

    import { defineConfig } from 'vite'
    import react from '@vitejs/plugin-react'
    import { manualChunksPlugin } from 'vite-plugin-webpackchunkname';
    
    // https://vitejs.dev/config/
    export default defineConfig({
      plugins: [react(), manualChunksPlugin()],
    })

     

    [ Suspense 컴포넌트 ]

    청크 파일을 필요할 때 로딩하다 보면 실행 중에 약간의 지연 시간이 발생할 수 있습니다. 지연 시간이 길어진다면 사용자에게 로딩 중임을 나타내는 화면을 보여주는 것이 좋습니다. 이런 화면을 fallback UI라고 부르며 이 기능을 손쉽게 구현할 수 있도록 도와주는 컴포넌트가 Suspense 컴포넌트입니다. 

     

    리액트 Suspense는 컴포넌트 내부에서 사용하는 데이터가 로딩 중이거나 데이터 로딩에 실패한 경우 예외를 throw하면 그 컴포넌트가 렌더링할 준비가 되지 않았다고 인식하고 fallback UI를 렌더링합니다. 처리가 완료되어 Promise가 정상적인 데이터를 응답하면 비로소 컴포넌트의 렌더링을 수행하여 데이터가 화면에 나타납니다.

     

    Suspense 컴포넌트의 사용 방법은 다음과 같습니다.

    // fallback 속성에는 발생한 지연 시간 동안에 보여줄 컴포넌트를 지정할 수 있습니다.
    // 1. 특정 컴포넌트를 감싸줄 수 있습니다. 
    <React.Suspense fallback={<Loading />}>
     <TextComponent />
    </React.Suspense> 
    
    // 2. <Router /> 컴포넌트도 감싸줄 수 있습니다.
    <React.Suspense fallback={<Loading />}>
     <Router>
     	......
     </Router>
    </React.Suspense>

     

    Suspense 컴포넌트는 일반적인 컴포넌트도 처리할 수 있지만 <Router /> 컴포넌트를 자식 컴포넌트로 포함할 수 있습니다.

     

    이 경우에 라우트 경로가 바뀔 때마다 필요한 청크 파일을 레이지 로딩하게 됩니다.

     

    Comments