typescript 项目中 vite 按需加载需代码组织、路由设计和构建配置三方面配合:路由级用动态 import() 声明组件,组件级用 defineasynccomponent 或 react.lazy,构建时通过 manualchunks 排除异步模块路径,并将 import() 绑定用户交互以解耦加载时机。

在 TypeScript 项目中,Vite 实现按需加载的核心是利用原生 ESM + 动态 import() 语法,配合构建时自动分包能力,把非首屏必需的代码延迟到真正需要时才加载。这不是“开个开关”就能生效的功能,而是需要你在代码组织、路由设计和构建配置三个层面主动配合。
路由级懒加载(最常用且见效最快)
Vue Router 或 React Router 都支持直接用动态导入声明组件,Vite 会自动将其拆成独立 chunk:
- 写法示例(Vue 3 + Vue Router):
{ path: '/admin', component: () => import('@/views/Admin.vue') } - 效果:访问
/admin时才请求Admin.vue及其依赖,首页完全不加载它 - 注意:不要写成
component: import('@/views/Admin.vue')—— 缺少箭头函数包裹会导致同步加载,失去懒加载意义
组件级按需加载(适合大功能模块)
对非路由入口但体积较大的 UI 组件或第三方功能模块,可用 defineAsyncComponent(Vue)或自定义 hook(React)封装:
- Vue 示例:
const HeavyChart = defineAsyncComponent(() => import('@/components/HeavyChart.vue'));
模板中像普通组件一样使用<heavychart></heavychart> - React 示例:
const HeavyChart = React.lazy(() => import('@/components/HeavyChart.tsx'));
配合Suspense处理加载状态 - 适用场景:弹窗、报表图表、富文本编辑器等用户操作后才出现的内容
Vite 构建配置辅助分包(避免误打包)
即使写了 import(),如果 Vite 的 build.rollupOptions.output.manualChunks 配置太宽泛,仍可能把懒加载模块提前打进主包:
- 错误配置示例:
id.includes('vue')—— 会把所有含 vue 字符串的路径都打进 vendor,包括异步加载的组件 - 推荐做法:
明确排除异步模块路径,例如:if (id.includes('src/views/') || id.includes('src/components/')) return 'async'; - 验证方式:构建后查看
dist/assets/目录,确认async-xxx.js类文件存在且未被合并进index-xxx.js
资源与逻辑的加载时机解耦(常被忽略)
按需加载不只是“代码要不要一起下”,更关键的是“什么时候触发下载”:
- 避免在
setup()或组件mounted中立即调用import()—— 这会让浏览器在渲染完成前就发起请求 - 更优策略:绑定到用户交互事件上,例如点击按钮后再
await import() - 搭配预加载提示(
import.meta.webpackPreload已过时,改用import(/* webpackPrefetch */ './X.vue')的等效写法):
Vite 支持注释式提示:import(/* vitePreload */ './utils/bigHelper.ts'),让浏览器空闲时预取











