Vue 3 的 Tree Shaking 特性
Vue 3 通过 Tree Shaking 实现按需引入,减少打包体积
问题
Vue 3 中的 Tree Shaking 特性是什么,如何使用?
解答
什么是 Tree Shaking
Tree Shaking 是一种通过清除多余代码来优化打包体积的技术,也叫 Dead Code Elimination(死代码消除)。它在保持代码运行结果不变的前提下,去除无用的代码。
简单比喻:传统方式像是把整个鸡蛋(带壳)丢进去搅拌做蛋糕,最后再挑出蛋壳;而 Tree Shaking 是一开始就只放入需要的蛋白蛋黄,直接做出蛋糕。
Vue 2 vs Vue 3
Vue 2 的问题
Vue 2 中,所有功能都会打包到生产代码中。因为 Vue 实例是单例的,打包工具无法检测哪些属性被使用:
import Vue from 'vue'
Vue.nextTick(() => {})
即使只用了 nextTick,整个 Vue 都会被打包进去。
Vue 3 的改进
Vue 3 将全局 API 分块,支持按需引入:
import { nextTick, observable } from 'vue'
nextTick(() => {})
只有导入的功能会被打包,未使用的功能不会包含在最终代码中。
实际对比
Vue 2 项目
基础组件:
export default {
data: () => ({
count: 1,
}),
};
添加 computed 和 watch 后:
export default {
data: () => ({
question: "",
count: 1,
}),
computed: {
double: function () {
return this.count * 2;
},
},
watch: {
question: function (newQuestion, oldQuestion) {
this.answer = 'xxxx'
}
}
};
打包体积不会变化,因为所有 API 都已包含在内。
Vue 3 项目
基础组件:
import { reactive, defineComponent } from "vue";
export default defineComponent({
setup() {
const state = reactive({
count: 1,
});
return {
state,
};
},
});
引入 computed 和 watch 后:
import { reactive, defineComponent, computed, watch } from "vue";
export default defineComponent({
setup() {
const state = reactive({
count: 1,
});
const double = computed(() => {
return state.count * 2;
});
watch(
() => state.count,
(count, preCount) => {
console.log(count);
console.log(preCount);
}
);
return {
state,
double,
};
},
});
打包体积会相应增加,因为新增了实际使用的功能。
工作原理
Tree Shaking 基于 ES6 模块语法(import 和 export),利用 ES6 模块的静态编译特性,在编译时就能确定模块依赖关系。
主要做两件事:
- 编译阶段利用 ES6 Module 判断哪些模块已加载
- 判断哪些模块和变量未被使用,删除对应代码
关键点
- Tree Shaking 通过按需引入减少打包体积,只打包实际使用的代码
- Vue 3 将全局 API 拆分为独立模块,支持按需导入
- 基于 ES6 模块的静态分析,在编译时确定依赖关系
- Vue 2 因为单例模式无法实现 Tree Shaking,所有功能都会被打包
- 带来更小的体积、更快的执行速度和更好的架构优化空间
目录