번들링은 여러 파일을 하나로 묶는 것을 말한다. 그냥 파일을 그대로 가져오면 편리함에도 번들링을 실행하는 이유는 단발성으로 리소스를 요청하는 HTTP 통신의 특성상 여러 번 파일을 요청하는 것보다 여러 파일을 한 번에 가져오는 것이 훨씬 효율적이기 때문이다. 이러한 측면에서 번들링은 최대한 빨리 리소스를 가져와서 사용자에게 화면을 제공해야 하는 프론트엔드 직무에서 매우 중요한 개념 중 하나이다.
리액트 어플리케이션들은 Webpack, Rollup, Browserify 등의 번들링 툴을 활용하여 하나의 파일로 통합할 수 있다. 심지어 리액트 어플리케이션을 만들기 위해 많이 사용하는 Create React App 혹은 최근 서버 사이드 렌더링과 함께 주목받고 있는 Next.js 등의 툴을 활용한다면 어플리케이션을 만들 떄 Webpack이 함께 제공된다.
기본적으로 번들링 툴들은 단순히 파일들을 묶어줄 뿐만 아니라 용량 압축, 구형 브라우저 지원 등 수많은 기능들을 함께 제공한다. 그럼에도 불구하고 시스템의 규모가 어느 정도 이상 커지게 되면 번들의 크기가 너무 커져서 로딩 시간이 길어지는 문제가 발생한다. 그리고 이는 자연스럽게 사용자 만족도의 하락으로 이어지게 된다. 번들의 거대화를 막기 위해서 리액트에서 공식적으로 제시하는 방법은 번들을 쪼개는 것이다. 코드 분할은 런타임에 여러 번들을 동적으로 불러오는 것을 말한다. 코드 분할은 코드를 줄이지 않으면서 어플리케이션의 초기 로딩 시간을 감소시켜 성능을 향상시켜 줄 수 있다. 코드 분할은 앞서 언급한 Webpack, Rollup, Browserify 등의 번들링 툴에서 지원하는 기능이다.
1. 동적 import
코드 분할을 위해 가장 권장되는 방법은 동적 import 문을 활용하는 것이다.
왼쪽 코드를 오른쪽과 같이 변경하게 된다면 dateHandler.js 파일을 따로 분할시킬 수 있다.
만약 default로 함수를 export하고 싶다면 아래와 같이 .default( )를 활용하면 된다.
2. React.lazy
React.lazy를 활용하면 동적 import를 통해 컴포넌트를 렌더링할 수 있다. React.lazy 컴포넌트는 무조건 Suspense 아래에 위치해야 한다. Suspense의 fallback을 활용하면 lazy 컴포넌트가 로딩될 때 까지 보여줄 예비 컨텐츠를 제공할 수 있다. 참고로 하나의 Suspense 안에 여러 lazy 컴포넌트가 들어갈 수도 있다.
3. 에러 경계 (Error Boundaries)
다른 모듈을 로드할 때 네트워크 장애 등의 이슈로 에러가 발생할 수도 있다. 이럴 때 에러 경계를 활용하면 코드 분할을 통해 다른 모듈을 불러오는 과정에서 발생하는 에러를 핸들링함으로써 사용자 경험을 개선할 수 있다. 단순히 이전 단계의 코드에서 Suspense를 에러 경계로 한 번 더 감싸주면 된다.
4. 라우트 기반 코드 분할 (Route-based code splitting)
React.lazy를 도입하기 가장 좋은 곳은 라우트이다. 웹 페이지를 불러오는 시간은 페이지 전환에 어느 정도 발생하며 대부분 페이지를 한 번에 렌더링하기 때문에 사용자가 페이지를 렌더링하는 동안 다른 요소와 인터렉션하지 않기 때문이다. (리액트 공식 문서 추출)
5. Named Exports
React.lazy는 default export만을 지원한다. 만약 named export와 React.lazy를 함께 사용하고 싶다면 default export로 재정의한 중간 모듈을 생성해주면 된다. 이렇게 하면 name exports를 활용하면서 코드 분할을 구현할 수 있다.
※ Named Export vs Default Export
- Name Export : export const something (한 파일에서 여러 개 export 가능)
- Default Export : export default something (한 파일에서 하나만 가능)
'프론트엔드 기본개념 복습 > React' 카테고리의 다른 글
[React] state 갱신하기 (0) | 2022.03.02 |
---|---|
[React] 에러 경계 (Error Boundaries) (0) | 2022.02.24 |
[React] React.memo, useCallback (0) | 2022.02.22 |
[React] 고차 컴포넌트(HOC) (0) | 2022.02.22 |
2021-09-28 React Component (0) | 2021.09.28 |