动态导入核心是将import()置于事件回调中实现按需加载,如click时用async/await调用并处理loading状态与错误,支持预加载和构建工具代码分割。

在用户点击时触发 JavaScript 动态导入,核心就是把 import() 调用放在事件处理函数中,而不是提前执行。这样模块不会在页面加载时下载,而是在点击那一刻才开始异步请求和加载。
把 import() 放进 click 事件回调里
这是最直接的方式:监听按钮或元素的点击事件,在回调中调用 import(),并用 await 或 .then() 处理后续逻辑。
- 确保
import()是动态字符串路径(不能是变量拼接的非常量表达式,否则打包工具无法静态分析) - 推荐使用
async/await写法,语义清晰且便于错误处理 - 模块加载成功后,通常要调用其中导出的函数或渲染组件
示例:
document.getElementById('loadChartBtn').addEventListener('click', async () => {
try {
const { renderChart } = await import('./charts.js');
renderChart(document.getElementById('chart-container'));
} catch (err) {
console.error('图表模块加载失败:', err);
}
});
配合加载状态提示用户体验
动态导入有网络延迟,用户点击后应给出即时反馈,比如禁用按钮、显示 loading 文案或骨架屏。
- 点击后立即设置按钮为
disabled,防止重复触发 - 可插入一个简单的 loading 元素,加载完成后再移除
- 避免用户误以为点击无响应
示例:
const btn = document.getElementById('loadChartBtn');
btn.addEventListener('click', async () => {
btn.disabled = true;
btn.textContent = '加载中...';
try {
const { renderChart } = await import('./charts.js');
renderChart(document.getElementById('chart-container'));
} catch (err) {
alert('加载失败,请重试');
} finally {
btn.disabled = false;
btn.textContent = '加载图表';
}
});
预加载提示(可选)提升感知性能
如果模块较大或网络较慢,可在鼠标悬停(mouseenter)时提前调用 import() 做预加载(不执行逻辑),等真正点击时再使用已缓存的模块。
- 注意:预加载只是让模块进入浏览器的模块图缓存,并不执行模块代码
- 需保存 Promise,避免多次触发重复请求
- 适合用户大概率会点击的场景(如主操作按钮)
示例:
let chartModulePromise = null;
const btn = document.getElementById('loadChartBtn');
btn.addEventListener('mouseenter', () => {
if (!chartModulePromise) {
chartModulePromise = import('./charts.js');
}
});
btn.addEventListener('click', async () => {
try {
const { renderChart } = await chartModulePromise;
renderChart(document.getElementById('chart-container'));
} catch (err) {
console.error(err);
}
});
注意 Webpack/Vite 等打包器的代码分割效果
动态 import() 是告诉构建工具“这里要切分代码”,但实际是否生成独立 chunk,还取决于模块内容和配置。
- Vite 默认对
import()自动分割;Webpack 需确保未被其他静态 import 引用过 - 路径尽量写死(如
import('./utils.js')),避免 webpack 无法识别而打到主包 - 可通过构建产物验证:查看 dist 目录下是否生成了类似
xxx.chunk.js的文件
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











