代码分割解决按需加载问题,tree shaking解决未用代码剔除问题;前者通过动态import实现路由/组件级懒加载,后者依赖esm静态分析剔除未引用导出。

Vue.js 组件化开发中,代码分割和 Tree Shaking 是两个互补但作用机制不同的优化手段:前者解决“不该一次性加载的代码”,后者解决“不该被打包进来的代码”。
代码分割让组件按需加载
核心是把大块逻辑拆成独立 chunk,在真正需要时才拉取。最常见、最有效的落地方式是路由级懒加载:
- 使用动态
import()语法替代静态import - Webpack/Vite 会自动识别并生成单独的 JS 文件(如
about.abc123.js) - 配合
/* webpackChunkName: "about" */或vite-plugin-dynamic-import可控命名与分组
例如:
// router/index.js
{
path: '/user',
component: () => import('@/views/UserPage.vue')
}
这样,用户访问首页时,UserPage.vue 及其依赖不会进入首屏 bundle。
组件级懒加载也适用类似逻辑:
<template><div>
<button true>打开弹窗</button>
<modal v-if="showDialog" false></modal>
</div>
</template><script setup>
import { defineAsyncComponent } from 'vue'
const Modal = defineAsyncComponent(() => import('@/components/Modal.vue'))
</script>
Tree Shaking 让未用代码不进包
它不是运行时判断,而是在构建阶段通过静态分析剔除未引用的导出项。生效前提很明确:
- 项目使用 ES Module 语法(
import/export),禁用 Babel 的modules: false - 第三方库提供 ESM 入口(检查
package.json中的"module"字段) - 避免全量导入写法,改用具名导入
- 正确设置
sideEffects字段,避免误删样式或 polyfill
比如使用 Element Plus:
// ❌ 全量引入 —— Tree Shaking 失效,整个库被打包
import ElementPlus from 'element-plus'
// ✅ 具名导入 + ESM 路径 —— 只打包用到的组件
import { ElButton, ElInput } from 'element-plus'
再配合 unplugin-vue-components 插件,模板里写 <elbutton></elbutton> 也能自动解析并只引入对应模块,无需手动 import。
两者协同效果更明显
代码分割减少首屏下载量,Tree Shaking 缩小每个 chunk 的体积。例如一个路由组件用了 lodash.debounce 和 dayjs 的部分功能:
- 动态导入该路由 → 它的 chunk 不会出现在首页
-
lodash支持 ESM +sideEffects: false+ 具名导入debounce→ chunk 里只有 debounce 函数,没有throttle、cloneDeep等 -
dayjs同理,只保留locale和format相关模块
最终,每个按需加载的 chunk 更轻、更精准。
不复杂但容易忽略
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










