按需引入通过tree shaking(构建时静态剔除)和dynamic import(运行时延迟加载)协同优化js性能。前者依赖es模块、库的esm入口及sideeffects声明;后者适用于非首屏大模块,支持魔法注释与路由懒加载。组件库需插件辅助实现真正按需,最终须验证产物体积与未用代码是否消失。

按需引入是 JavaScript 性能优化中减少无用代码执行最直接有效的方式,核心靠两套机制协同:Tree Shaking(构建时静态剔除)和 Dynamic Import(运行时延迟加载)。两者目标一致——不让没用的代码进内存、不执行、不传输,但作用阶段和适用场景不同。
Tree Shaking:构建时“摇掉”未引用的导出
它不是自动生效的魔法,依赖三个硬性条件同时满足:
-
必须用 ES 模块语法:只识别
import/export,require()或module.exports完全无效 -
第三方库得提供 ESM 入口:检查库的
package.json是否有"module": "es/index.js"字段;优先选lodash-es、date-fns、Element Plus这类原生支持的库 -
项目要声明副作用范围:在根目录
package.json中设"sideEffects": false;若引入了 CSS 或 polyfill,就显式列出:"sideEffects": ["*.css", "src/polyfill.js"]
导入写法也很关键:import { debounce } from 'lodash-es' 可被摇掉未用函数;而 import _ from 'lodash' 或 import * as antd from 'antd' 会强制保留整个模块。
Dynamic Import:运行时“按需拉取”模块
适合大体积、非首屏必需、用户触发才用的功能模块,比如富文本编辑器、图表库、后台管理子页面等。它把代码分割成独立 chunk,只在真正需要时发起请求:
- 语法简单:
const { default: Editor } = await import('./Editor.vue')(Vue SFC)或import('chart.js').then(({ Chart }) => {...}) - 支持 Webpack/Vite 的魔法注释,控制 chunk 命名和预加载:
/* webpackChunkName: "charts" */、/* webpackPrefetch: true */ - 和路由配合最自然:Vue Router 的
component: () => import('./views/Setting.vue'),React Router 的lazy(() => import('./pages/Report'))
组件库的按需加载不能只靠 JS 层
Vue 或 React 模板里写了 <el-button></el-button> 却没手动 import,Tree Shaking 无法关联,可能导致全量打包或运行时报错。这时需要插件辅助:
- Vue 项目推荐
unplugin-vue-components+ 对应 resolver(如ElementPlusResolver()),它会在编译期扫描模板标签,自动生成命名导入语句 - 旧项目若用 Ant Design,可搭配
babel-plugin-import,把import { Button } from 'antd'自动转为import Button from 'antd/es/button' - 避免在组件内部顶层写副作用逻辑,例如
document.body.appendChild(...)或修改原型,否则整块文件可能因“有副作用”被保留
验证效果比配置更重要
再完美的设置也要看产物是否真变小了:
- Vite 用户运行
vite build --report,打开生成的report.html查看依赖图和模块大小 - Webpack 用户加
--stats=verbose或用webpack-bundle-analyzer插件可视化分析 - 直接搜索最终 bundle 文件,确认你没用的函数名(比如
throttle)是否还存在;如果存在,说明 Tree Shaking 没走通,回头检查 ESM 支持、副作用声明或导入方式
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











