Tree Shaking

IT공부중·2021년 2월 22일
0

frontend

목록 보기
7/16

직역하면 나무 흔들기, 모듈을 번들링할 때 사용하지 않는 코드를 제거하는 최적화 과정을 말한다.

이 용어를 처음 최적화 개념에 사용한건 rollup.js이다. Webpack 4 부터 대단히 영리한 최적한 빌드를 보여준다.

Webpack의 optimization에서 provideExports: true (기본값) 을 사용하여 사용하지 않는 코드는 안 불러오게 된다.

import * as A from '~'; 조차도 최적화됨

모든게 되는건 아니고 commonjs로 된 것은 안 된다. ES Module로 의존성을 관리하는 모듈만 Tree Shaking을 한다.

development 단계에서는 사용되지 않고, production 모드로 실제 배포를 위해 번들링할 때만 적용된다.

import * from 'module1';
import * from 'module2';
import * from 'module3';

이렇게 작성하고 번들링을 수행하면 webpack은 해당 모듈 안에 있는 모든 코드를 가져오게 된다. 가져온 function 중 일부만 사용하고 싶어도 전부를 번들링 하게 된다.

반면에 import로 모듈을 불러올 때 필요한 함수만 불러오게 되면 webpack에서 쓰지 않는 함수들을 번들링 과정에서 제거하고 최적화된 파일을 받을 수 있게 된다.

import { function1 } from 'module1';
import function6 from 'module3/function6';

이런식으로 가져오면 webpack에서 쓰지 않는 함수들을 번들링 과정에서 제거하고 최적화된 파일을 받을 수 있게 된다.

그렇게 되면 bundle.js 크기도 줄어들게 된다.

Tree Shaking 조건

Tree shaking 을 하기 위해서는 일종의 조건이 필요하다.

ES Module을 사용하는지 확인해야한다.

해당 패키지가 ES Module (import) 을 사용하고 있는가이다. ES Module이 중요한 이유는 위 예제에서도 알 수 있듯 사용하는 함수만 명식하기 위해서 import 구문을 사용하는데, 설계 방식에서 ES Module을 사용하지 않는 패키지에서는 적용할 수 없다. 가령 lodash 패키지의 경우 CommonJS 모듈을 사용하기 때문에 tree shaking을 사용하기 위해서는 ES 구문을 지원하는 lodash-es 패키지를 대신 사용해야한다.

또는 바벨이 js 파일을 트랜스파일링 하는 과정에서 ES Module을 CommonJS로 변환하는지도 확인해야한다. IE에서는 ES6 문법을 지원하지 않기 때문에 babel을 사용하면 범용적인 ES5 버전으로 트랜스파일링을 거치는 경우가 많다. 그 과정에서 import 구문까지 변환하기 때문에 webpack에서는 어떤 함수만 번들하면 되는지 확인할 수 없게 된다.

이것을 막으려면 .babelrc 파일에서 babel-preset-env의 modules 옵션을 false로 설정 하면 commonJS로 트랜스파일링 되는 상황을 방지할 수 있다.

Side Effect 고려하기

Side Effect가 발생하는지를 고려해야한다. 사용하지는 않지만 다른 코드에 영향을 미칠 수 있다고 판단하는 경우 사이드 이펙트가 발생했다고 하는데, 이렇게 사이드 이펙트가 발생하는 경우에는 webpack에서 필요 없는 파일을 판단할 수가 없어서 tree shaking을 수행하지 않는다.

이러한 사이드 이펙트는 webpack이 자체적으로 발생 여부를 판단할 수 없어서 package.json의 sideEffects 옵션을 확인하고 유무를 판단한다. package.json 파일에서 sideEffectsfalse로 설정하면 webpack이 플래그를 인식하여 사이트 이펙트가 없다고 판단하고 Tree Shaking을 수행한다.

참고자료
https://brunch.co.kr/@swimjiy/24

profile
4년차 프론트엔드 개발자 문건우입니다.

0개의 댓글