lazy로 인한 번들 사이즈 증가??

강성훈·2023년 4월 12일
0

기술면접

목록 보기
5/9

코드 스플리팅이란

왜 필요할까?

자바스크립트로 개발하게 될 경우 기본적으로 하나의 번들 파일에 모든 로직이 들어가게 된다. 이는 프로젝트의 규모가 커질수록 번들 파일 또한 끊임 없이 커진다는 것을 의미하게 된다. 그렇게 된다면 당연히 페이지가 로딩 되는 속도가 저하될것이다.

자바스크립트

기존 자바스크립트에선 import() 함수를 통하여 분리가 가능하다.
import() 함수 형태로 메서드 안에서 사용하게 되면 필요할 때 해당 스크립트를 불러오게 되는 것이다.

react에서 import() 함수를 통한 분리는 어떻게 작동할까

// src/add.js
export default function add() {
  console.log('add');
}

// src/App.js
import React from 'react';

const App = () => {
  	const clickEvent = () => {
    	import("./add.js").then((res) => res.default()); 
    }
	return <div></div>
}

import 함수를 통해 반환된 값은 promise로 resolve되었을 때 우리가 내보낸 default라는 이름의 add 함수를 default()로 실행시킨 것이다.

React Lazy, Suspense

react에서 lazy와 suspense로 코드 스플리팅을 지원한다.
react에선 lazy를 쓰지 않고 코드 스플리팅을 한다면 state를 통해 해당 모듈이 필요할 경우 state를 바꾸는 방식으로 분리하였다. 하지만 꽤나 귀찮은 작업이었고 이를 위해 lazy와 suspense가 등장하였다.

lazy

먼저 lazy란 비동기적으로 컴포넌트를 렌더링 하는 시점에 분리된 파일을 가지고 오도록 하는 함수이다.

suspense

lazy와 같은 코드 스플리팅을 적용하게 된다면, 분리된 파일을 렌더링 되는 시점에 가져오게 되므로 로딩 시간이 걸리게 된다. 그럴 경우 suspense fallback을 이용하여 분리된 파일이 로딩되기전에 보여줄 화면을 설정할 수 있도록 해준다.

import React from 'react';

const AddComponent = React.lazy(() => import("./AddComponent"));

const App = () => {
	return (
        <Suspense fallback={<div>Loading...</div>}>
          <AddComponent />
        </Suspense>
    );
}

번들 사이즈 증가?

코드 스플리팅을 하게 되면 전체 번들사이즈가 커지는 이슈가 존재한다.

increases-entry-bundle-size

다음 스택오버플로우에 글에 따르면

기존 568kb였던 번들 파일에서 코드 스플리팅을 적용하였다.

그랬더니 593kb로 번들사이즈가 약 25kb가 증가하게 된 것이다.
25kb가 왜 증가하게 되었을까

다양한 추측

이 이유에 답을 다양하게 추측해보았다.
1. 단순히 lazy와 suspense를 사용하였기에 용량 증가
2. 파일별로 중복된 모듈 여러번 작성
...

증가하게 된 이유

webpck code splitting에 따르면 다음과 같은 항목이 존재하였다.

  • 항목 청크 사이에 중복된 모듈이 있으면 두 번들에 모두 포함됩니다.

즉 청크 별로 react와 같은 중복된 모듈을 여러번 생성하니 용량이 늘어나게 된것이다.

해결

const path = require('path');

 module.exports = {
   mode: 'development',
   entry: {
    index: {
      import: './src/index.js',
      dependOn: 'shared',
    },
    another: {
      import: './src/another-module.js',
      dependOn: 'shared',
    },
    shared: 'lodash',
   },
   output: {
     filename: '[name].bundle.js',
     path: path.resolve(__dirname, 'dist'),
   },
   optimization: {
    runtimeChunk: 'single',
  },
 };

다음과 같이 dependOn을 이용하여 중복 방지가 가능하다.

이미지 출처:
https://appdividend.com/2022/01/24/javascript-import/

profile
고등학생 주니어 개발자

0개의 댓글