React 코드 스플리팅

·2023년 6월 9일
0

개발 지식

목록 보기
89/96
post-thumbnail

code spliting

리액트 앱의 코드를 여러 개의 번들로 나누는 기술. 코드 스플리팅 자체는 리액트만의 기술이 아니며, 모듈 번들러를 활용하여 다른 SPA 라이브러리에서도 사용이 가능한 기술이다.

SPA의 경우, 빌드를 통해 모든 코드를 파일하나로 합추는 작업이 진행되는데, 코드가 많아질수록 소스 코드에 대한 컴파일링 시간은 증가하게 되고, 그만큼 초기 렌더링이 늦어지는 단점을 가지게 된다.

이를 개선하고자 코드에서 당장 사용한 부분을 먼저 파싱하여 렌더링한 후, 이후에 필요한 코드 부분은 따로 이후에 파싱하도록 분리하도록 하는 것이 코드 스플리팅의 특징이라 할 수 있다.

코드 스플리팅을 하는 경우, main.js 외에 숫자로 시작하는 다른 js 파일들이 생성하는 것을 볼 수 있다. 숫자로 쓰인 부분은 실제 필요한 경우에만 해당하여 불러와 사용하게 된다.

dynamic import

기존 import의 경우, 코드 가장 상위에서 사용하여, 먼저 필요한 파일을 불러온 후 작업이 이루어지게 하는데, 이를 static import (정적 불러오기) 라고 한다.

이와 반대로, 먼저 필요한 코드를 불러오지 않고, 개발자가 필요하다고 판단하는 시점에 비동기적으로 모듈을 가져오는 방식을 dynamic import라 한다. dynamic import를 사용하면, 어플리케이션 실행 중에 필요한 경우에만 해당 모듈을 가져올 수 있다는 점에서 실행 시간을 단축하는데 도움을 준다.

// 필요한 모듈을 동적으로 로드
async function loadModule() {
  const module = await import('./module.js');
  // 로드한 모듈 사용
  module.doSomething();
}

// 버튼이 클릭 될 때 모듈 부르기
button.addEventListener('click', loadModule);

일반적으로 자바스크립트 문서에는 static import를 강조하는 편이다. 가독성에도 좋고, 모듈의 사전 로드가 가능한것도 있지만 번들링시에 큰 이점이 존재한다. static import를 사용하는 것이, 모듈을 모아 하나의 번들 파일로 묶는 구조화를 통해 캐싱을 최적화 할 수 있고, 사용하지 않는 import를 찾아 트리쉐이킹을 하기도 한다.

React.lazy

리액트 어플리케이션을 개발한다면 코드 스플리팅을 위해 lazy() 함수를 사용하는 것이 가능하다. lazy() 를 사용한 컴포넌트는 해당 컴포넌트가 렌더링 될 때 까지, 해당 컴포넌트를 로드 하지 않는다.

사용방법은 기존에 사용하던 lazy() 의 콜백함수로 dynamic import를 실행하면 된다.

// import Main  from "./components/pages/Main;

const Main = React.lazy(() => import("./components/pages/Main"));

React.lazy() 와 dynamic import 차이

두 방식 모두 React 에서 코드 스플리팅의 방법으로 권장하는 방식이다. 비동기적으로 개발자가 필요할 때 코드를 따로 나눠 불러오는 기능은 같지만, dynamic import의 경우, Promise 객체를 반환하고 React.lazy 의 경우 null 과 분할된 컴포넌트를 반환한다.

또한 lazy() 만 가진 특징으로 React.Suspense 와 함께 활용할 수 있다는 점이 있다. Suspense() 와 함께내 사용하게 되면, 해당 lazy() 컴포넌트가 다 불러오기 전까지 fallback() 컴포넌트를 대신 보여준다.

import React, {lazy, Suspense} from 'react';

export interface Iprops {
    src: string,
    name: string,
}

const LazyImage = lazy(() => import('./LazyImage')); // 이미지를 그리는 컴포넌트를 lazy 시켰습니다. lazy는 동적 import를 사용하는 함수를 인자로 넣어줘야합니다.

const LazyItem = ({src, name}: Iprops) => {
    return (
        <div>
            <Suspense fallback={<div>...loading</div>}> // 컴포넌트가 다 불러오기 전까지 ...loading이라는 컴포넌트를 보여줍니다. Suspense를 사용하지 않으면 에러가 납니다.
                <LazyImage src={src} name={name}/> // 다 불러와지면 해당 컴포넌트를 보여줍니다.
            </Suspense>
            {name}
        </div>
    );
};

export default LazyItem;

참고
React.lazy 사용해보기
Dynamic import(동적 가져오기)
[React] 리액트에서 코드 스플리팅
동적으로 모듈 가져오기
dynamic import와 React.lazy

profile
새로운 것에 관심이 많고, 프로젝트 설계 및 최적화를 좋아합니다.

0개의 댓글