html本身不支持代码分割,真正实现需依赖javascript模块系统或构建工具;关键在于运行时按需加载、避免预下载未用代码,常见方式包括动态import()、webpack splitchunks及vite自动分包。

HTML 本身不支持代码分割(Code Splitting)——它只是静态标记语言,没有模块加载、动态导入或打包能力。所谓“HTML 做代码分割”,实际是指在基于 HTML 的前端项目中,通过 JavaScript 生态(如 Webpack、Vite、React、ES Modules)配合 HTML 入口,实现资源的按需加载。
为什么直接在 HTML 里写 <script src="big.js"></script> 不算代码分割
这种写法会阻塞解析、强制同步加载整个文件,哪怕只用其中 10% 的功能。真正的代码分割必须满足:「运行时决定加载哪些代码」+「不提前下载未使用部分」。
常见错误现象:Uncaught SyntaxError: Cannot use import statement outside a module(直接在普通 script 中写 import())、页面首屏白屏时间长、Lighthouse 报告提示「减少未使用的 JavaScript」。
关键点:
- HTML 只负责声明入口(如
<script type="module" src="main.js"></script>),分割逻辑全在 JS 层 - 必须启用模块系统(
type="module")或构建工具(Webpack/Vite)才能触发动态导入 - 纯静态 HTML + 普通 script 标签无法实现真正的 code splitting
用 import() 动态导入实现路由级分割(React/Vue/原生 ES Module)
这是最常用、兼容性较好(Chrome 63+、Firefox 67+、Safari 11.1+)的方式,适用于按钮点击、路由切换等明确触发时机。
示例(原生 ES Module 场景):
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
// main.js
document.getElementById('load-chart').addEventListener('click', async () => {
const { renderChart } = await import('./charts/chart-lib.js');
renderChart();
});
注意:
-
import()返回 Promise,必须用await或.then() - 路径必须是字符串字面量(不能是变量拼接),否则 Webpack/Vite 无法静态分析生成 chunk
- Vite 默认支持;Webpack 需确保
optimization.splitChunks开启(默认已开) - 不要在顶层作用域写
import(),否则等效于静态导入
Webpack 中配置 splitChunks 自动提取公共模块
当你有多个入口(如 index.html 和 admin.html)且共用 lodash、moment 等库时,手动拆分易出错,交给 Webpack 更稳。
典型配置(webpack.config.js):
optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: {
vendor: {
test: /[\/]node_modules[\/](react|react-dom|lodash)[\/]/,
name: 'vendor',
priority: 10,
reuseExistingChunk: true
}
}
}
}
影响说明:
-
chunks: 'all'表示同时处理async(动态导入)和initial(入口)模块 - 若不加
priority,可能被其他 cacheGroup 覆盖;reuseExistingChunk: true防止重复打包 - 构建后你会看到
vendor.js和多个xxx.chunk.js,HTML 中由 Webpack 自动生成对应<script></script>标签
Vite 项目中如何让 <script type="module"></script> 正确加载分割后的 chunk
Vite 默认启用代码分割,但如果你在 HTML 中手写 <script type="module" src="main.js"></script>,而 main.js 用了 import(),仍需确认两件事:
- Vite 开发服务器能正确解析并返回
.jschunk(默认支持,无需额外配置) - 生产构建后,
index.html中的 script 标签是否被 Vite 自动注入了 hash 和完整路径(是的,只要用vite build,不是手动复制) - 如果自己用
fs.writeFileSync写 HTML,务必用manifest.json查找真实 chunk 名,不能硬编码chunk.xxxx.js
容易忽略的一点:Vite 的 build.rollupOptions.output.entryFileNames 若被自定义为不含 hash(如 'assets/[name].js'),会导致浏览器缓存旧 chunk —— 分割后更新失效问题比单文件更隐蔽。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










