build를 진행하다 터미널에 위의 문구가 나타났다.
번들 크기가 권장보다 훨씬 크다는 경고문구인데, 배포 된 사이트에서도 일부 스타일이 손실되는 문제가 발생하였다.
모바일, 노트북에서는 문제가 없었는데 데스크탑에서만 해당 문제가 일어남.
왜 그런지는 찾아봐야 할 것 같다..수정 : 2024-04-16
위에서 말한 일부 스타일 손실 문제는 CloudFront에서 Cache된 파일을 사용하여 파일명이 맞지 않아 생긴 오류였으며, 캐시 무효화 설정을 통해 해결하였다.
Create-React-App 으로 제작한 리액트 프로젝트기 때문에 해당 패키지를 사용하였다.
Installation
# NPM npm install --save-dev cra-bundle-analyzer # Yarn yarn add -D cra-bundle-analyzer
Usage
npx cra-bundle-analyzer
패키지를 설치 한 뒤, 실행 명령어를 입력하면 build 폴더에 report.html이 생성된다.
live server를 이용하여 report.html을 확인해보자
번들 트리맵이 보이며, 각 영역에 마우스를 올리면 번들 사이즈가 Stat size, Parsed size, Gzipped size 로 나눠져 있다.
Stat, Parsed, Gzipped 은 각 번들의 사이즈 측정 기준이다.
Stat은 빌드된 그대로의 상태, Parsed는 웹팩이 트리셰이킹을 마친 결과물, Gzipped는 결과적으로 서빙을 위해 압축된 사이즈이다.
Gzipped size는 Parsed size의 파일을 gzip 압축한 후의 크기이므로 Parsed size를 줄이면 자연스레 Gzipped size도 줄게 된다.
따라서 이 둘을 줄이는 것을 목표로 하면 된다.
코드 스플리팅은 자바스크립트 번들을 더 작은 청크로 나누어 필요한 코드만 로딩함으로써 로딩 시간을 최적화하는 방법이다.
React에서는 lazy와 suspense를 이용하는 방법이 있다.
React.lazy
컴포넌트를 렌더링하는 시점에 비동기적으로 로딩할 수 있게 해주는 유틸 함수React.suspense
코드 스플리팅된 컴포넌트를 로딩하며, 로딩이 끝나지 않았을 때 보여줄 UI를 설정할 수 있다.
예시 코드
import React, { Suspense, lazy } from 'react';
const Component = React.lazy(() => import('./Component'));
const myComponent = {
return (
<Suspense fallback={<div>Loading...</div>}>
<Component />
</Suspense>
)
}
라우트 단위로 코드 스플리팅을 적용하는 것이 일반적이라 하여 적용해보았다.
기존 코드
페이지가 너무 많아서 일부분만 가져와서 진행
// App.tsx function App() { return ( <> <ScrollToTop /> <Routes> {/* 로그인 한 유저만 접근 가능 */} <Route element={<MainLayout />}> <Route path={"/dashboard"} element={<Dashboard />} /> <Route path={"/waste"} element={<History />} /> <Route path={"/diary"} element={<Diary />} /> </Routes> <ToastContainer style={{ fontSize: "1.4rem" }} /> </> ); }
원래 크기: 4.69MB
최적화 후 크기: 1.51MB
크기 감소 비율: 약 68%
프로젝트에서 사용하지 않는 패키지들을 정리하는 것도 사이즈를 줄이는 데 도음이 될 것이다.
하지만 일일히 파일을 순회하며 사용하지 않는 것을 찾는 일은 고되므로.. 도구를 사용해보자.
프로젝트의 종속성을 분석하여 어떤 종속성이 사용되지 않는지, package.json에서 누락되었는지 확인 가능한 도구이다.
Installation
npm install -g depcheck
Usage
npx depcheck
실행하면 아래와 같이 정보가 제공된다.
사용하지 않은 종속성 목록을 참고하여 삭제를 진행해주면 된다.
depcheck는 개발할 때 주기적으로 해주면 좋을 듯 하다..
로컬 환경에서 LightHouse 를 이용하여 비교한 결과
최적화 전
최적화 후
Code Splitting 이 성능 향상에 큰 영향을 줬다.
Suspense를 사용할 때 fallback으로 빈 div를 넘겨주다보니 UX가 저하된 것 같다.
이를 해결하기 위해선 Skeleton Component를 제작해야 하는데 시간이 많이 소요 될 작업이라 생각하여 어떻게 해결해야 할지 고민 해 볼 예정이다.