- 프로젝트 최적화 - bundle analyzer를 사용해 bundle size 줄이기 (+ Gzip)2025년 01월 19일 14시 33분 15초에 업로드 된 글입니다.작성자: 동혁이
프로젝트 최적화 - bundle analyzer를 사용해 bundle size 줄이기
Bundle이란?
여러 개의 파일을 하나로 묶어서 처리하는 것을 의미합니다. JavaScript 파일들을 묶어서 생성되며, 웹 애플리케이션에서 필요한 리소스를 단일 파일로 묶어 관리하고 전달하는 데 사용된다.
웹 애플리케이션의 경우 HTML, CSS, Javascript로 구성되는데 이들을 따로 모두 요청하게 되면 서버-클라이언트 요청 교환 횟수가 늘어나고 응답시간이 느려질 수 있는데 이런 필요한 파일들을 하나로 묶어 사용해 크기를 줄이고 요
청횟수를 줄인다.
일반적인 react앱과 달리 nextjs앱은 기본적으로 코드스플리팅을 지원해 페이지별로 필요한 스크립트만 번들링하게 된다.
하지만 그렇다하더라도 불필요한 스크립트가 같이 번들링되는 일이 있어 따로 최적화할 수 있다면 해야하는 것 같다.그렇다면 어떻게 줄일 수 있을까요?
1) 불필요한 모듈 삭제 및 불필요한 모듈 import 제거
2) Code Splitting
Nextjs가 코드스플리팅을 통해 페이지별로 필요한 모듈들만 번들링 해 제공하여 초기 로드 속도를 향상시킨다고 하니 추가적으로 불필요한 파일을 찾아 제거하고 클라이언트 사이드에서만 필요한 모듈들을 선정해 동적으로 로드시키는 것은 꽤 중요해 보인다.
그렇다면 이 번들파일이 어떻게 구성되었는지 세부적인 내용을 어떻게 볼 수 있을까?
bundle-analyzer로 번들 파악하기
- 번들 파일이 어떻게 구성되었는지 쉽게 보여주는 시각화 도구 입니다.
설치 방법
npm install @next/bundle-analyzer --save-dev or yarn add -D @next/bundle-analyzer
적용 방법
1) next.config.js에 아래와 같이 넣어줍니다.
import withBundleAnalyzer from '@next/bundle-analyzer'; const bundleAnalyzer = withBundleAnalyzer({ enabled: process.env.ANALYZE === 'true', openAnalyzer: true, }); const nextConfig = { / ... / }; export default bundleAnalyzer(nextConfig);
2) package.json의 scripts에 아래 명령어를 추가하고 실행시켜줍니다.
"analyze": "ANALYZE=true next build"
https://www.npmjs.com/package/@next/bundle-analyzer
@next/bundle-analyzer
Use `webpack-bundle-analyzer` in your Next.js project. Latest version: 15.1.5, last published: 2 days ago. Start using @next/bundle-analyzer in your project by running `npm i @next/bundle-analyzer`. There are 217 other projects in the npm registry using @n
www.npmjs.com
명령어를 실행시키면 빌드가 완료된 후
위와 같이 .next 안에 처음보는 analyze 폴더가 생기고 아래 client, edge, nodejs.html 파일이 생깁니다.
client.html - 클라이언트 번들링 결과를 시각적으로 분석한 결과물 edge.html - 서버에서만 필요한 모듈의 번들링 결과를 시각적으로 분석한 결과물 nodejs.html - 서버 사이드 렌더링 시 필요한 모듈의 번들링 결과를 시각적으로 분석한 결과물
client.html에 사용자에게 전달될 모든 번들 파일과 사용하는 패키지가 시각화 되어있습니다.
전체적인 크기
확실히 lottie 라이브러리가 크기가 엄청 크네요..
마우스를 올려보면 이런식으로 나옵니다.
(https://www.npmjs.com/package/webpack-bundle-analyzer#size-definitions)
Stat size : Minification, Uglify 등의 변형이 일어나기 전의 크기 Parsed size : Minification, Uglify 등의 변형이 일어난 후의 크기 (최적화 후), 브라우저에서 파싱 후, 실행될 크기 Gzipped size : Gzip 알고리즘으로 압축된 파일 크기, 네트워크를 통해 전송되는 크기
즉, Parsed size와 Gzipped size를 줄인다면, 브라우저에서 자바스크립트를 다운로드하고 실행하는 시간과 네트워크 상에서 전송되는 시간을 단축시킬 수 있습니다.
페이지별 번들
chunk 번들
적용
1) Next.js dynamic적용
- 빌드 시점에 용량을 차지하지 않습니다.
- Lottie 라이브러리 dynamic import
const Lottie = dynamic(() => import('lottie-react'), { ssr: false });
2) 더 가벼운 라이브러리 lottie-light-react 사용
npm i lottie-light-react or yarn add lottie-light-react
위 dynamic을 아래와 같이 변경
const Lottie = dynamic(() => import('lottie-light-react'), { ssr: false });
https://www.npmjs.com/package/lottie-light-react
lottie-light-react
Lottie for React (lottie light). Latest version: 2.4.0, last published: 2 years ago. Start using lottie-light-react in your project by running `npm i lottie-light-react`. There are 4 other projects in the npm registry using lottie-light-react.
www.npmjs.com
기존 제일 큰 크기의 lottie 라이브러리가 안보입니다. (구웃!)
main 페이지 번들 181kB -> 175kB 감소 (큰 변화는 없는 것 같습니다.)
Gzip compress(압축)하기
Gzip이란 파일 압축에 쓰이는 응용 소프트웨어로써, HTML, CSS, JS 등을 압축하여 리소스를 받는 시간을 줄여주는 방식으로 성능을 개선할 수 있습니다. 약 1/3 ~ 1/4 정도로 번들 용량을 압축해준다고 합니다!
여기서 하나 알고 가야할게 있습니다.
1. Next.js에서는 기본으로 Gzip을 지원합니다. - 서버 응답 시점에서 동적으로 gzip 압축 한다는 특징이 있습니다. 2. compression-webpack-plugin의 gzip 지원 - 빌드 시점에 정적으로 .gz 파일을 미리 생성합니다.
즉, 실시간 압축과 미리 압축의 차이로 실제 프로덕션 환경에서는 미리 압축된 파일을 사용하는 것이 서버 부하를 줄일 수 있어서 compression-webpack-plugin을 사용하는 것이 더 권장된다고 합니다.
기존 빌드 후 결과물은 큰 용량의 js 파일들밖에 없습니다.
설치
npm install compression-webpack-plugin --save-dev or yarn add -D compression-webpack-plugin
적용
import CompressionPlugin from 'compression-webpack-plugin'; import withBundleAnalyzer from '@next/bundle-analyzer'; const bundleAnalyzer = withBundleAnalyzer({ enabled: process.env.ANALYZE === 'true', openAnalyzer: true, }); const nextConfig = { reactStrictMode: true, webpack(config) { / ... / // 아래 코드추가 if (!config.mode.includes('development')) { config.plugins.push(new CompressionPlugin()); } return config; } }; export default bundleAnalyzer(nextConfig);
최적화 전 LightHouse
최적화 후 LightHouse
결론
SI: 1.7s -> 1.5s
CLS: 0으로 수렴
bundle-analyzer를 통해 Lottie를 최적화 할 수 있었고 gzip을 통해 압축을 해볼 수 있는 시간이었습니다.
큰 변화는 얻지 못했지만 새로운 지식과 경험을 얻을 수 있는 좋은 기회가 된 것 같고
최적화 작업은 익숙하지 않지만, 신선하고 재미있었습니다.
웹 서비스의 성능은 사용자 경험, 유추와 직접적으로 관계가 있다고 생각하기 때문에 항상 도전의식이 있는 영역이였는데, 부족하게나마 성능을 개선하고 lighthouse를 통해 시각적으로 확인할 수 있어 더욱 재밌게 느껴졌던 것 같습니다.
앞으로는 더욱 다양한 방법으로 성능 개선을 해보고 싶은 마음이 들었으며, 저와 같이 익숙하지 않은 분들에게 도움이 되길 바라며 글을 마치도록 하겠습니다. 감사합니다.
다음글이 없습니다.이전글이 없습니다.댓글