About Tree Shaking

Reduce the bundle size by eliminating dead code (데드 코드를 제거하여 번들사이즈를 줄이기)

The original post is from https://www.patterns.dev/posts/tree-shaking/

가끔 우리는 어디에도 우리 앱에서 쓰이지 않는 코드를 작성하기도 한다. 죽은 코드 조각들은 번들 사이즈를 줄이기와 불필요하게 더 많은 데이터를 적재하는 것을 막기 위해서 제거될 수 있다! 우리의 번들에 넣기 전에 데드 코드를 제거하는 프로세스를 tree-shaking (트리 쉐이킹)이라고 한다.

트리 쉐이킹은 math와 같은 간단한 모듈들에서 동작하기도 하지만, 트리 쉐이킹이 꽤나 까다로운 케이스들도 있다.

Concepts

트리 쉐이킹은 최종 자바스크립트 번들에서 쓰이지 않는 코드를 제거하는데 목적을 갖고 있다. 올바르게 작업이 된다면, 자바 스크립트 번들의 사이즈를 줄일 수 있고, 더 가볍게 다운로드 할수 있으며 파싱과 실행 시간을 줄일 수 있다. 모듈 번들러 (웹팩이나 롤업과 같은)를 사용하는 모던 자바스크립트 앱들을 위해서, 번들러들은 자동으로 당신의 예상대로 죽은 코드를 없앤다.

당신의 어플리케이션과 그것의 추상적인 신택스 트리 디펜던시들을 고려해 보라. (우리는 그 신택스 트리를 최적화 하기위해서 "shake" 하고 싶다.) 트리 내부의 각각의 노드는 당신의 앱을 기능하게 하는 디펜던시들 이다. 트리쉐이킹에서, input file들은 그래프로 취급된다. 각 그래프의 각각의 노드는 코드의 "part"라고 불리는 최상위 레벨의 상태이다. 트리쉐이킹은 순환하는 그래프이다. 엔트리포인트 부터 시작하여 포함하는 어떤 것들을 경로에 따라 모두 순회한다.

모든 컴포넌트는 심볼, 심볼 레퍼런스를 선언할수 있고 다른 파일들에 의존적이다. "parts"가 사이드이펙트를 가지고 있다고 표시되어 있든 아니든간에 말이다. 예를 들면, let firstName = 'Jane'이라는 선언은 사이드이펙트가 없다. 왜냐면 저 선언은 만약 어떤데에서도 firstName을 쓰지 않는다면 제거될수 있기 때문이다. let firstName = getName()이라는 선언은 사이드이펙트를 가지고 있다. 왜냐하면 getName()이라는 함수는 지워질수 없기때문이다. 만약 아무도 firstName이라는 변수를 쓰지 않아도 말이다.

Imports

ES2015 모듈 신택스(importexport)를 따라서 선언된 모듈들만이 트리쉐이킹을 할 수 있다. 당신이 모듈을 임포트하는 방식이 그 모듈이 트리쉐이킹 할수 있는지 여부를 나타낸다.

트리쉐이킹은 사이드 이펙트와 함께 엔트리 포인트의 모든 파트들을 거치면서 시작된다. 그리고 새로운 섹션에 도달할때 까지 그래프의 가장자리들까지 순회한다. 순회가 완료된다면, 자바스크립트 번들은 순회가 이루어지는 동안에 도달한 부분들만 포함한다. 그 외의 조각들은 포함되지 않는다. 다음과 같은 utilities.js라는 파일을 만들었다고 해보자:

export function read(props) {⁣⁣
    return props.book⁣⁣
}⁣⁣
⁣⁣
export function nap(props) {⁣⁣
    return props.winks⁣⁣
}

그리고 다음과 같은 index.js 파일이 있다:

import { read } from 'utilities';⁣⁣
⁣⁣
eventHandler = (e) => {⁣⁣
    read({ book: e.target.value })⁣⁣
}

예시에서, nap()은 중요하지 않다. 그러므로 번들에 포함되지 않는다.

Side Effects

우리가 ES6 모듈들을 임포트 할때, 이 모듈은 즉시 실행된다. 우리가 어디에서도 모듈의 exports들을 코드에서 언급하진 않더라도, 모듈 자체가 실행될때 글로벌 스코프에 영향을 미치면서 발생 할수 있다. (polyfill 혹은 global stylesheets 같은 것들) 우리는 이것을 사이드 이펙트 (side effect)라고 부른다. 모듈 자체의 exports를 언급하지 않더라도, 만약 모듈이 시작과 함께 값들을 exports 한다고 하면, 모듈은 트리쉐이킹 될 수 없다. 그것이 import될때에 특정한 행동 동안에는 말이다.

Webpack 다큐먼트가 트리 쉐이킹의 명확한 설명을 해준다. 그리고 어떻게 트리쉐이킹을 잘하게 만드는지도 알려준다.

← Go home