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,
    }),
};

添加 computedwatch 后:

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,
    };
  },
});

引入 computedwatch 后:

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 模块语法(importexport),利用 ES6 模块的静态编译特性,在编译时就能确定模块依赖关系。

主要做两件事:

  1. 编译阶段利用 ES6 Module 判断哪些模块已加载
  2. 判断哪些模块和变量未被使用,删除对应代码

关键点

  • Tree Shaking 通过按需引入减少打包体积,只打包实际使用的代码
  • Vue 3 将全局 API 拆分为独立模块,支持按需导入
  • 基于 ES6 模块的静态分析,在编译时确定依赖关系
  • Vue 2 因为单例模式无法实现 Tree Shaking,所有功能都会被打包
  • 带来更小的体积、更快的执行速度和更好的架构优化空间