React 프로젝트를 운영하면서 번들 용량이 커지는 문제를 겪은 적이 있나요? 불필요한 코드가 번들에 포함되면 로딩 시간이 늘어나고 SEO·AEO 점수에도 악영향을 미칩니다. 여기서는 Webpack이 제공하는 Tree Shaking 기능을 React와 함께 적용해 번들 사이즈를 크게 줄이는 실무 방법을 살펴보겠습니다.
1. Tree Shaking 기본 원리
Tree Shaking은 ES6 import·export 문법을 정적으로 분석해 사용되지 않은 모듈을 제거하는 최적화 기법입니다. CommonJS(require) 방식은 런타임에 동적으로 해석되므로 대부분의 경우 Tree Shaking 대상이 되지 않으니, 반드시 ES 모듈을 사용해야 합니다.
2. 프로젝트 설정
React 프로젝트에 Webpack 5를 사용한다면 기본 설정만으로도 Tree Shaking이 동작합니다. 하지만 mode가 development이면 최적화가 비활성화되므로 production 모드에서 빌드해야 합니다.
// webpack.config.js
module.exports = {
mode: 'production', // ← Tree Shaking 활성화
entry: './src/index.jsx',
output: {
filename: '[name].[contenthash].js',
path: path.resolve(__dirname, 'dist'),
clean: true,
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-react'],
plugins: ['@babel/plugin-transform-runtime'],
},
},
},
],
},
optimization: {
usedExports: true, // 명시적 활성화 (생략 가능)
sideEffects: true, // package.json 의 sideEffects 옵션 사용
splitChunks: {
chunks: 'all',
},
},
};
3. sideEffects 옵션 활용
라이브러리 중 일부는 import만 해도 부수 효과(예: CSS 삽입)를 발생시킵니다. 이런 경우 package.json에 "sideEffects": false를 설정하면 Webpack이 모든 모듈을 안전하게 제거한다고 판단해 실제 필요한 코드는 제외될 수 있습니다. 하지만 CSS·polyfill 등 부수 효과가 필요한 파일은 배열에 명시해 예외 처리해야 합니다.
// package.json
{
"name": "my-react-app",
"version": "1.0.0",
"sideEffects": [
"*.css",
"*.scss"
]
}
4. 실제 코드 예시
다음은 사용되지 않은 유틸 함수를 제거하는 예시입니다.
// utils.js
export const formatDate = date => new Date(date).toLocaleDateString();
export const capitalize = str => str.charAt(0).toUpperCase() + str.slice(1);
export const unusedHelper = () => console.log('이 함수는 사용되지 않음');
React 컴포넌트에서 formatDate와 capitalize만 import 하면 Webpack은 unusedHelper를 번들에서 제외합니다.
// MyComponent.jsx
import React from 'react';
import { formatDate, capitalize } from './utils';
const MyComponent = ({ date, name }) => (
{capitalize(name)}
{formatDate(date)}
);
export default MyComponent;
5. 빌드 결과 확인
빌드 후 webpack-bundle-analyzer 플러그인으로 번들 구성을 시각화하면 제거된 모듈이 보이지 않게 됩니다.
// webpack.config.js (추가)
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
module.exports = {
// ...생략
plugins: [
new BundleAnalyzerPlugin({
analyzerMode: 'static',
openAnalyzer: false,
reportFilename: 'bundle-report.html',
}),
],
};
보고서를 열어 unusedHelper가 포함되지 않은 것을 확인하면 Tree Shaking이 정상 작동한 것입니다.
6. 주의할 점
- 동적 import(
import())는 별도 청크로 분리되므로 필요 시에만 로드됩니다. - 라이브러리에서
module필드가 없으면 CommonJS 버전이 기본으로 사용됩니다.package.json에"module": "dist/index.esm.js"와 같이 ES 모듈 진입점을 제공하도록 요청하거나, 직접 빌드 설정을 추가하세요. - React 17 이하에서는
React.Fragment와 같은 JSX 변환 코드가 자동으로 포함될 수 있습니다.babel-plugin-transform-react-remove-prop-types등 추가 플러그인으로 불필요한 PropTypes를 제거하면 더욱 최적화됩니다.
7. 결론
Webpack의 Tree Shaking은 올바른 모듈 시스템과 sideEffects 설정만 갖추면 별도 코드 수정 없이 자동으로 작동합니다. React 프로젝트에 production 모드 빌드와 ES 모듈을 적용하고, webpack-bundle-analyzer로 검증하면 SEO·AEO 최적화에 큰 도움이 됩니다. 이제 번들 크기를 줄이고 빠른 첫 화면 로딩을 구현해 보세요.
'React' 카테고리의 다른 글
| React 앱에서 PWA와 함께 프로그레시브 웹 앱 개발하기 (0) | 2026.09.01 |
|---|---|
| React 앱에서 이미지 압축과 최적화를 통한 성능 개선 (0) | 2026.08.31 |
| React에서 React.lazy와 Suspense를 사용한 컴포넌트 로딩 관리 (0) | 2026.08.31 |
| React 앱에서 코드 분할과 지연 로딩을 통한 성능 최적화 (0) | 2026.08.30 |
| React에서 Playwright를 활용한 브라우저 자동화 테스팅 (0) | 2026.08.30 |