React 같은 CSR 페이지를 로딩하는 경우, 개발을 진행하고 코드를 빌드 시키면 생성되는 번들 파일을 로딩하는 과정을 거치는데 이 과정에서 번들 파일이 무거운 경우 로딩 속도가 느려져 사용자는 마냥 흰색 화면만 보고있어야 되는 경우가 생겨 UX 에 좋지 않는 상황이 발생한다. 번들 파일이 무거운 이유는 접속한 페이지의 코드 뿐만 아니라 다른 페이지에서만 사용되는 코드들도 전부 가져오기 때문이다. 이 문제를 Code Splitting 으로 해결할 수 있다.
정의
Chunk 파일을 통해 코드들을 분리하여 번들 파일의 크기를 줄이는 것
예제
해당 예제는 React 환경에서 진행되었습니다.
ex) 사용자가 home 페이지에 있는 경우
함수
Before
- 하나의 메인 번들 파일만 존재한다. (main.bundle.js)
- 버튼을 클릭하지 않아도 메인 번들 파일에서
homePageFunction()
함수를 확인할 수 있다.
- about 페이지에서만 사용되는
aboutPageFunction()
이 메인 번들 파일에서 확인된다.
After
- 메인 번들 파일에서
homePageFunction()
를 찾을 수 없다.
- 버튼을 클릭하면 utils/home-utils.js 의 chunk 파일이 따로 생성되고 그 파일 안에
homePageFunction()
이 확인된다. (src_utils_home-utils_js.chunk.bundle.js)
aboutPageFunction()
도 똑같이 코드 스플리팅이 적용되었기 때문에 메인 번들 파일에서 찾을 수 없다.
import()
를 사용해서 함수를 동적으로 가져온 뒤, 함수를 가지고 있는 파일을 chunk 파일로 따로 분리시킨다.또한
import()
는 Promise 를 반환하기 때문에 catch()
를 통해 예외 처리도 가능하다.컴포넌트
Before
- 하나의 번들 파일만 존재한다. (main.bundle.js)
- 메인 번들 파일에서 Introduce 컴포넌트가 확인된다.
After
- 메인 번들 파일(main.bundle.js) 과 Introduce 컴포넌트의 chunk 파일이 생성된다. (src_components_Introduce_js.chunk.bundle.js)
- Introduce 컴포넌트에 대한 정보는 메인 번들 파일에 존재하지 않고 Introduce 컴포넌트 chunk 파일에서만 확인이 가능하다.
React.lazy()
를 통해 컴포넌트를 import 한 다음, 컴포넌트를 적용하는 페이지에서 Suspense
의 하위 영역에 방금 import 한 컴포넌트를 적용시켜주면 컴포넌트를 chunk 파일로 생성시켜준다. 또한 Suspense
의 fallback
props 를 통해 컴포넌트가 로딩중인 경우의 UI 도 표현이 가능하다.경로 기반 코드 분할
ex) Home 페이지에 접속한 경우
Before
- 하나의 번들 파일만 존재한다. (main.bundle.js)
- 메인 번들 파일에서 Home 컴포넌트와 About 컴포넌트 모두 확인된다.
After
- 메인 번들 파일과 Home 컴포넌트의 chunk 파일이 생성된다. (src_components_Home_js.chunk.bundle.js)
- Home 컴포넌트에 대한 정보는 메인 번들 파일에 존재하지 않고 Home 컴포넌트 chunk 파일에서만 확인이 가능하다.
- About 페이지에 접근하면 기존에 존재하지 않았던 About 컴포넌트의 chunk 파일이 생성된다. (src_components_About_js.chunk.bundle.js)
- About 컴포넌트에 대한 정보 또한 메인 번들 파일에 존재하지 않고 About 컴포넌트 chunk 파일에서만 확인이 가능하다.
react-router-dom 라이브러리를 사용하여 route 를 설정하고 각각의 페이지에 해당하는 컴포넌트들을
React.lazy()
와 Suspense
를 사용하여 Chunk 파일을 생성하였다.테스트 사항
Barrel 형식 환경에서의 Code Splitting
ex) About 컴포넌트에서 Ohter 폴더의 index.js 를 통해 OtherComponentA 컴포넌트만 사용한 경우
Before
- 하나의 번들 파일만 존재한다. (main.bundle.js)
- OtherComponentB 컴포넌트를 사용하지 않았지만 메인 번들 파일에서 코드가 확인된다. (불필요)
After
- 메인 번들 파일과 OtherComponentA 컴포넌트의 chunk 파일이 생성된다. (src_components_Other_OtherComponentA_js.chunk.bundle.js)
- 메인 번들 파일에서 OtherComponentB 컴포넌트의 정보가 확인되지 않는다.
- OtherComponentB 컴포넌트를 사용하지 않았기때문에 chunk 파일이 생성되지 않는다.
출처