아무 작업을 하지 않았을 경우 대부분 하나의 Bundle 파일이 보일 것이다. 하지만 Bundle의 사이즈가 커지게 되면 페이지의 첫 진입이 느려지는 불편함이 발생 할 수도 있기 때문에 Code Splitting이라는 기술을 이용하여 Bundle의 코드를 특정한 기준을 가지고 다양한 Bundle로 분할하게 되었다.
Code Splitting는 크게 Entry Points 와 Dynamic Import 방식으로 접근할 수 있으며 Entry Points의 경우 엔트리 청크 사이에 중복된 모듈이 있는 경우 두 번들에 모두 포함때문에 Prevent Duplication 작업이 추가적으로 필요하다.
const Main = lazy(() => import('../pages/MainPage'));
const Search = lazy(() => import('../pages/SearchPage'));
const Notfound = lazy(() => import('../pages/NotFoundPage'));
const ROUTE = [
{ path: PATH.MAIN, Component: Main, auth: false },
{ path: PATH.SEARCH, Component: Search, auth: false },
{ path: PATH.NOT_FOUND, Component: Notfound, auth: false },
];
export { ROUTE };
나의 경우에는 React Router를 이용하여 url에 따라 컴포넌트를 불러오고 있기 때문에 해당 컴포넌트들을 기준으로 Code Splitting 작업을 진행하였더니 기존에 비해 약 40kb정도 줄어든 것을 확인할 수 있었다.
여기서 조금 더 욕심을 내면 Vendor Chunk를 활용할 수 있다.
Vendor Chunk는 node_moudules와 같이 외부에서 관리되는 모듈들만 따로 분류하는 chunk로 Vendor Chunk를 사용하면 매번 빌드될때마다 hash값이 바뀌지 않기 때문에 재배포하여도 이미 캐싱된 chunk 파일을 활용하여 조금 더 빠르게 로딩할 수 있는 장점이 있다.
분리된 vendor chunk는 재배포가 되어도 동일한 hash값을 가지고 있기 때문에 사용자 입장에서 브라우저에 캐싱된 파일을 불러와 그만큼 더 빠르게 로딩할 수 있게 된다.
또 줄일 수 있는 포인트는 웹 폰트이다.
폰트를 사용할 시점에 다운로드를 받기 때문에 그만큼 로딩이 느려지고 있다. 크롬의 경우에는 5~6개의 파일을 병렬적으로 처리할 수 있기 때문에 preload옵션을 사용하면 로딩 시점을 앞당길 수 있으며 FBConf Korea의 웹폰트의 사용과 최적화 세션을 보게 되면서 단순하게 폰트의 형식을 바꾸는 것만으로도 성능 개선이 가능하다고 하여 폰트의 형식도 woff -> woff2 포맷으로 변경하였다.
기존에 사용했던 woff 사이즈는 455KB 정도였다.
변경 후에는 약 60퍼 정도 절감된 효과를 얻을 수 있었고 index.html을 읽어오는 시점에 폰트를 미리 로드하여 로딩 시점을 앞당길 수 있었다.
해당 서비스는 유튜브에 존재하는 음악영상 목록을 활용하여 나만의 플레이리스트를 만들어 음악을 들을 수 있는 서비스로 저장해둔 음악(이미지포함)이 많아질수록 초기 로딩속도에 영향을 미칠 수 있다.
따라서 현재 viewport에 보이는 이미지만 우선적으로 불러올 수 있도록 Image lazy loading를 적용하게 되었다.
사실 해당 프로젝트 규모는 작기 때문에 굳이 하지 않아도 충분히 첫 화면 로딩이 빨랐다. 하지만 공부하는 입장이기 때문에 조금이라도 성능차이를 느껴보고 싶어 시작하게되었는데 위의 과정만으로도 처음보다 확연하게 줄어든 용량(약 1.3MB)과 빨라진 로딩성능(약 65%)을 확인할 수 있었다.