출처 : https://en.wikipedia.org/wiki/Tree_shaking
코드를 최적화할 때 사용하는 [dead code elimination](https://en.wikipedia.org/wiki/Dead-code_elimination)
기술. 동적 언어에서 죽은 코드 제거는 정적 언어보다 훨씬 어렵다고 한다(런타임에 실행되기에 사용 여부를 알기가 어려워서 참조)
이 용어를 대중화한 Rollup.js
는 CommonJS와 달리 ES6 모듈의 로딩이 정적이므로 분석 및 추론이 가능하다는 사실에 기반을 두고 있음.
이를 통해 import를 통해 가져오는 코드를 정적으로 분석하고, 사용되지 않는 모든 것을 제외함으로써 코드의 크기를 최적화함.
최근 RxJS에 대해 공부하고 있었는데 이런 내용을 발견했다.
… Rx의 초창기는 Event를 Array처럼 다루는 개념으로 시작한 것이기에 Array의 Method 문법과 많이 닮아 있었습니다. 그러나 이후 module과 번들 개념이 도입되고 RxJS의 기본 덩치가 커짐에 따라서 Method 방식은 Tree-Shaking에 불리하다는 문제가 있었습니다.
출처 : RxJS 한번 배워보실래요? | 테오의 프론트엔드 | 요즘IT
왜 메소드 방식은 Tree-Shaking에 불리할까!
바로 테스트해보기로 했다.
소스코드 : https://github.com/bluejoyq/vite-bundle-test
vanila-ts
로 프로젝트 초기화import { defineConfig } from 'vite'
// https://vitejs.dev/config/
export default defineConfig({
build: {
minify: false,
}
})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + TS</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
import { User } from "./lib";
const user = new User();
user.getName();
export class User {
name : string;
constructor() {
this.name = 'bluejoy';
}
getName() {
return this.name;
}
setName(name : string) {
this.name = name;
}
}
export const setName = (name : string, user : User) => {
return user.name = name;
}
yarn build
/dist/assets/*.js
을 열어보자class User {
constructor() {
__publicField(this, "name");
this.name = "bluejoy";
}
getName() {
return this.name;
}
setName(name) {
this.name = name;
}
}
const user = new User();
user.getName();
setName
메서드는 호출되지 않았지만 포함됨.setName
함수는 호출되지 않았으므로 포함되지 않음.main.ts
에 setName('bluejoy', user);
을 추가 시 번들에 포함됨.class
의 method
(정확하게는 prototype
을 통한 객체의 method
)는 tree shaking
을 현재로써는 하지 않는다.