D.evelop/React

[React] 코드 분할 Code-Splitting (번들링)

Danne 2021. 12. 15. 09:17

공식문서 - https://ko.reactjs.org/docs/code-splitting.html

 

번들링이란?

 

앱이 커지면 번들도 커진다.

큰 규모의 서드 파티 라이브러리를 추가할 때 실수로 앱이 커져서 로드 시간이 길어지는 것도 주의해야하는 부분이다.

 

코드 분할  Code-Splitting

  • 번들이 거대해지는 것을 방지하는 방법
  • 런타임에 여러 번들을 동적으로 만들고 불러오는 것
  • Webpack, Rollup과 Browserify (factor-bundle) 같은 번들러가 지원하는 기능
  • 코드 분할은 여러분의 앱을 “lazy-load” 하게 도와줌
  • 앱의 코드 양을 줄이지 않고도 사용자가 필요하지 않은 코드를 불러오지 않게함
    앱의 초기화 로딩에 필요한 비용을 줄여줍니다.

 


✅ 동적 import()문법

// Before
import { add } from './math';

console.log(add(16, 26));
// After
import("./math").then(math => {
  console.log(math.add(16, 26));
});
  • Webpack이 이 구문을 만나게 되면 앱의 코드를 분할함

 

 

 React.lazy

  • React.lazy 함수를 사용하면 동적 import를 사용해서 컴포넌트를 렌더링 할 수 있음
import React, { Suspense } from 'react';

/*
React.lazy는 동적 import()를 호출하는 함수를 인자로 가집니다.
이 함수는 React 컴포넌트를 포함하며 
default export를 가진 모듈로 결정되는 Promise로 반환해야 합니다.
*/
const OtherComponent = React.lazy(() => import('./OtherComponent'));
const AnotherComponent = React.lazy(() => import('./AnotherComponent'));

function MyComponent() {
  return (
    <div>
      <Suspense fallback={<div>Loading...</div>}>
       {/*Suspense 컴포넌트는 lazy 컴포넌트를 감쌉니다. 
        하나의 Suspense 컴포넌트로 여러 lazy 컴포넌트를 감쌀 수도 있습니다.*/}
        <section>
          {/*lazy 컴포넌트*/}
          <OtherComponent />
          <AnotherComponent />
        </section>
      </Suspense>
    </div>
  );
}
    • MyComponent가 처음 렌더링 될 때 OtherComponent를 포함한 번들을 자동으로 불러온
    • lazy 컴포넌트는 Suspense 컴포넌트 하위에서 렌더링되어야 함.
      Suspense는 lazy 컴포넌트가 로드되길 기다리는 동안 로딩 화면과 같은 예비 컨텐츠를 보여줄 수 있게 해준다.
    • fallback prop은 컴포넌트가 로드될 때까지 기다리는 동안 렌더링하려는 React 엘리먼트를 받아들입니다. 

Route-based code splitting

앱에 코드 분할을 어느 곳에 도입할지?

사용자의 경험을 해치지 않으면서 번들을 균등하게 분배할 곳!

  • Route
    대부분 페이지를 한번에 렌더링하기 때문에 사용자가 페이지를 렌더링하는 동안 다른 요소와 상호작용하지 않음.

 


Named Exports

React.lazy는 현재 default exports만 지원

// ManyComponents.js
export const MyComponent = /* ... */;
export const MyUnusedComponent = /* ... */;

 

named exports를 사용하려면 default로 이름을 재정의한 중간 모듈을 생성할 수 있음.

// MyComponent.js
export { MyComponent as default } from "./ManyComponents.js";

 

이렇게 하면 tree shaking이 계속 동작하고 사용하지 않는 컴포넌트는 가져오지 않는다.

// MyApp.js
import React, { lazy } from 'react';
const MyComponent = lazy(() => import("./MyComponent.js"));

 

반응형