본문 바로가기

React-Native

react-native webpack size exceeds the recommended limit (244 KiB)가 발생하는 경우

반응형

개인프로젝트개발이 마무리단계에 접어들어서 react-native-web을 배포하는 중에 겪었던 issue를 정리겸 포스팅합니다.

react-native를 web으로 배포하려면 webpack이라는 모듈을 사용해 배포하는데,

외부 library등으로 인해 bundle 사이즈가 커지는 경우, build된 bundle 사이즈가 244kib가 넘는다는 경고가 나타납니다.

물론, 해당 경고는 경고일 뿐 기능하는데는 문제가 없지만 성능저하가 있을 수 있다고 합니다.

해소방법과 회피방법 하나씩 소개드리겠습니다.

 

해소방법:

  1. webpack-bundle-analyzer를 활용해 크기가 큰 bundle을 식별한다.
  2. 식별된 bundle을 lazy loading 방식이나 optimizer를 다운로드해 해소한다.

저는 해소방법 2번 중에 lazy loading방식을 활용해서 정적으로 로드되던 폰트를 동적으로 로드되게끔 변경했습니다!

 

1. webpack-bundle-analyzer를 활용해 크기가 큰 bundle 식별

$npm install --save-dev webpack-bundle-analyzer

로 webpack-bundle-analyzer를 다운로드 받습니다.

이후, $(project_root)/package.json 에 build를 위한 명령어와

webpack 설정파일인 webpack.common.js에 다운로드 받은 plugin을 사용한다는 내용을 작성합니다.

 

package.json:

  "scripts": {
    ...
    "build-react": "webpack --config ./webpack.prod.js",
    "start-react": "webpack serve --config ./webpack.dev.js",
    ...
  },

 

webpack.common.js

 

  plugins: [
	...
    new BundleAnalyzerPlugin({
      analyzerMode: 'static',
        reportFilename: 'bundle-report.html',
        openAnalyzer: false,
        excludeAssets: [/node_modules/]
    }),
  ]

 

webpack.dev.js와 webpack.prod.js 파일은 각각 아래와 같습니다.

webpack.dev.js

const path = require('path');
const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');

module.exports = merge(common, {
  mode: 'development',
  devtool: 'inline-source-map',
  devServer: {
    port: 8083,
    open: true,
    historyApiFallback: true,
    static: path.resolve(__dirname, 'dist'),
    hot: true,
  }
});

 

webpack.prod.js

const path = require('path');
const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');

module.exports = merge(common, {
    mode: 'production',
    optimization: {
        splitChunks: {
          minSize: 10000,
          maxSize: 250000,
        }
    }
});

 

이후, react-native-web을 빌드합니다.

$npm run build-react

 

빌드가 완료되고나면,  $(project_root)/dist 디렉토리가 생성됩니다.

이 디렉토리에 bundle-report.html 이 생성되게 되는데, 이 파일이 사용중인 bundle을 크기별로 가시화한 파일입니다.

bundle-report.html

이 파일을 브라우저로 열면, 아래와 같이 크기별로 어느 bundle이 큰지 가시화됩니다.

저의 경우, MaterialIcons.ttf 폰트가 가장 컷는데, 해당폰트를 index.web.js에서 import할 때 lazy loading 기법을 사용해 해소했습니다.

 

 

2. 식별된 bundle을 lazy loading 방식을 적용

index.web.js

import { AppRegistry } from 'react-native';
import App from './App.web';
import { name as appName } from './app.json';
import { Platform } from 'react-native';

if (Platform.OS === 'web') {
  import('react-native-vector-icons/Fonts/MaterialIcons.ttf')
    .then((MaterialIcons) => {
      const style = document.createElement('style');
      style.type = 'text/css';
      style.appendChild(document.createTextNode(`
        @font-face {
          src: url(${MaterialIcons.default});
          font-family: MaterialIcons;
        }
      `));
      document.head.appendChild(style);
    })
    .catch((error) => console.error('Error loading fonts:', error));
}

AppRegistry.registerComponent(appName, () => App);

if (Platform.OS === 'web') {
  AppRegistry.runApplication(appName, {
    initialProps: {},
    rootTag: document.getElementById('app'),
  });
}

 

원래는 무조건 css에 로드되게끔 개발되었었는데, MaterialIcons가 완전히 import된 경우에만 css에 로드되도록 코드를 변경했습니다.

여기까지가 lazy loading을 활용한 bundle크기를 줄이는 방법이었습니다!

 

회피방법:

회피방법은 간단합니다.

경고가 나오는 마지노선인 244Kib를 늘리는 겁니다!

webpack.prod.js 에서 performance.maxEntrypointSize, performance.maxAssetSize 를 필요한 만큼 늘려줍니다.

webpack.prod.js:

const path = require('path');
const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');

module.exports = merge(common, {
    mode: 'production',
    performance: {
        hints: false,
        maxEntrypointSize: 512000,
        maxAssetSize: 512000
    },
    optimization: {
        splitChunks: {
          minSize: 10000,
          maxSize: 250000,
        }
    }
});

 

간단한 회피방법이지만, bundle크기를 더 이상 줄일 수 없을때 사용해야지 싶습니다.

 

Reference:

https://velog.io/@buddle6091/%EB%B3%B8%EA%B2%A9%EC%A0%81%EC%9C%BC%EB%A1%9C-Webpack-Optimize-%ED%95%98%EA%B8%B0-Bundle-Chunk-Minimize

 

본격적으로 Webpack Optimize 하기 (Bundle Analyzer, Chunk, Minimize, Uglify)

이제 Webpack을 통하여 본격적인 Optimize를 진행해보려고 한다! 사실 Webpack5가 도입이 되면서 아주 기본적인 최적화를 default로 진행을 해준다고 한다. 하지만, 이외의 Plugin과 Optimaization 옵션을 적절

velog.io

https://stackoverflow.com/questions/49348365/webpack-4-size-exceeds-the-recommended-limit-244-kib

 

Webpack 4 "size exceeds the recommended limit (244 KiB)"

I have two files which are combined under 600 bytes (.6kb) as below. So how is it that my app.bundle.js is so large (987kb) and more importantly how does one manage the size of it? src file index...

stackoverflow.com

 

반응형

'React-Native' 카테고리의 다른 글

React-Native 안전하게 프로젝트이름 변경하기  (0) 2024.08.17