动态导入解决了静态import导致的首屏体积大、白屏时间长、无法按需/条件加载模块等核心问题;它在运行时异步加载模块并返回Promise,支持表达式路径,典型用于路由分割、条件加载和错误降级。

动态导入(import())是 ES2020 正式引入的特性,面试中常被用来考察对模块系统、加载时机和工程实践的理解。高效回答的关键不是背语法,而是讲清“为什么需要它”“它解决了什么老问题”“用在哪儿最合理”。
动态导入解决了什么核心问题
静态 import 在模块解析阶段就确定依赖,所有代码一次性加载,导致:
- 首屏体积大、白屏时间长(尤其含大型图表库、编辑器、国际化包)
- 用户没点到某功能,却提前加载了对应逻辑(如“导出 PDF”按钮对应的 pdf-lib)
- 无法根据运行时条件(如权限、设备类型、A/B 实验分组)决定加载哪个模块
和静态 import 的本质区别
重点不是“写法不同”,而是加载时机与返回值:
-
import { foo } from './a.js':编译时分析,必须存在,报错在构建阶段 -
import('./a.js').then(...):运行时调用,返回 Promise,可try/catch捕获失败(如网络中断、404) - 支持表达式:
import(`./locales/${lang}.js`)或import(`./pages/${route}.js`)
典型使用场景(带简短代码示意)
面试官爱听“有业务感”的例子,避免只说“按需加载”:
-
路由级代码分割:React Router / Vue Router 的 lazy loading 就基于它
const Home = () => import('./views/Home.vue') -
条件加载:仅在用户点击“高级设置”后加载配置面板组件
button.addEventListener('click', async () => { const { AdvancedPanel } = await import('./AdvancedPanel.js'); render(AdvancedPanel); }); -
错误降级:加载失败时展示轻量替代方案
try { const heavy = await import('./HeavyChart.js'); heavy.render(); } catch { fallbackChart.render(); }
注意事项(体现深度)
不是所有地方都适合用,要主动提限制:
- 不能出现在模块顶层(否则变成静态 import),只能在函数作用域内调用
- Webpack/Vite 会自动为其生成独立 chunk,但若路径是完全动态的(如
import(userInput)),打包工具无法预知,可能 fallback 到整个 node_modules - SSR 环境需配合
dynamic import的服务端处理(如 Next.js 的dynamic)


















