组件懒加载用 import() 实现,本质是动态加载而非初始化打包;需配合 Vue 的 defineAsyncComponent 或 React 的 lazy/Suspense;路径必须为字符串字面量,且 import() 返回 Promise。

组件懒加载用 import() 语法实现,本质是让组件在需要时才动态加载,而不是初始化就打包进主包。关键不是写法多复杂,而是理解它如何触发代码分割、怎么配合 Vue 或 React 的异步组件机制,以及哪些地方容易出错。
懒加载的基本写法:import() 返回 Promise
import() 是一个动态导入函数,返回一个 Promise,resolved 后得到模块对象(默认导出在 .default 上)。不能写成常规 import,否则 Webpack / Vite 会静态分析并提前打包。
- ✅ 正确(动态,可被分割):
const MyComponent = () => import('./MyComponent.vue') - ❌ 错误(静态,无法分割):
import MyComponent from './MyComponent.vue' - ⚠️ 注意:路径必须是字符串字面量(不能拼接变量),否则构建工具无法静态分析生成 chunk
在 Vue 中配合 defineAsyncComponent 使用
Vue 3 推荐用 defineAsyncComponent 包裹动态 import,支持 loading、error 状态处理:
import { defineAsyncComponent } from 'vue'
<p>const AsyncModal = defineAsyncComponent({
loader: () => import('./components/Modal.vue'),
loadingComponent: LoadingSpinner,
errorComponent: ErrorPanel,
delay: 200,
timeout: 5000
})</p>
-
loader必填,返回 import() Promise -
delay控制 loading 组件延迟显示(避免闪动) -
timeout防止加载卡死,超时后抛错触发errorComponent
在 React 中配合 Suspense 和 lazy
React 需要搭配 lazy + Suspense,且 lazy 只接受 default 导出:
import { lazy, Suspense } from 'react'
<p>const Dashboard = lazy(() => import('./Dashboard'))</p><p>function App() {
return (
<suspense fallback="<Spinner"></suspense>>
<dashboard></dashboard>
)
}</p>
- 确保
Dashboard.jsx用export default,否则会报 “Element type is invalid” -
Suspense必须包裹懒加载组件,fallback是加载中 UI - 错误边界(Error Boundary)需单独加,
Suspense不捕获错误
进阶技巧:命名 chunk、预加载与条件加载
可通过 webpackChunkName 注释控制生成的 chunk 文件名,便于调试和缓存管理:
const Chart = () => import(/* webpackChunkName: "chart" */ './Chart.vue')
- Vite 用户写
/* @vite-ignore */无用,应改用/* webpackChunkName: "chart" */(Vite 兼容该注释) - 需要预加载(比如 hover 时提前 fetch):调用
import()但不 await,只触发下载 - 按路由、权限、A/B 测试等条件加载:把 import() 放在 if / switch 内部,只要路径是静态字符串即可
不复杂但容易忽略。核心就三点:用 import() 而非 import、路径写死、配合框架的异步组件封装。拆出来的 chunk 会被自动注入 HTML,无需手动管理 script 标签。











