html无原生按需加载组件能力,实际依赖js控制资源时机,通过data-module声明模块并驱动加载,配合type="module"脚本中动态import()调用,路径须为字符串字面量,且需处理脚本执行、样式隔离、事件清理与xss防护。

HTML 本身不提供“按需加载组件”的原生能力,所谓按需,实际是靠 JS 控制资源加载时机,并配合 HTML 的语义化结构和属性做触发与配置。直接写 <component src="xxx.html"></component> 会报错,也不存在这种标签。
用 data-module 声明模块并驱动加载
这是最可控、可维护的起点。把模块类型和参数写在 HTML 元素上,JS 根据它决定加载什么、传什么参数。
-
data-module值必须是白名单内的字符串(如"chart"、"modal-terms"),不能直接当路径拼接使用 -
data-src用于传 API 地址或模板路径,相对路径以当前 HTML 文件为基准,不是 JS 文件位置 - 避免用
class="module-chart"这类隐式标记——难校验、易冲突、无法存结构化数据 - 初始化前先检查该元素是否已加载过模块,防止重复执行
import()或重复绑定事件
动态 import() 必须在 type="module" 脚本中调用
你不能在普通 <script></script> 里写 import('./mod.js'),浏览器会直接报 Unexpected token 'import'。
- 入口脚本必须声明
<script type="module"></script>,否则import()语法不被识别 -
import()只能在函数作用域内调用,比如按钮点击回调、路由守卫、IntersectionObserver触发时 - 路径只能是字符串字面量或模板字符串常量:
import('./charts/bar.js')✅,import('./' + name + '.js')❌(构建工具无法拆包) - 必须用
await或.then()消费 Promise,裸写import(...)不会报错但模块导出不可用
加载后注入 HTML 片段要小心脚本执行和 XSS
用 fetch 拉回一段 HTML 字符串再塞进 innerHTML,看着简单,但默认不执行其中的 <script></script>,也不加载 data-src 图片。
-
<script></script>标签不会自动运行,需手动提取、创建节点、插入document.head或目标容器 - 若内容来自可信后台(如 CMS 导出的静态片段),可用
DOMParser解析后遍历script标签,再用eval()或createElement('script')注入(⚠️仅限可信源) - 含
img的src会自动加载,但data-src、background-image: url(...)不会,得额外解析替换 - 服务端返回的 HTML 必须确保无用户输入直出,否则
innerHTML = rawHtml是典型 XSS 入口
别忽略样式隔离和资源复用边界
按需加载不是只管 JS 加载完就行,CSS 和 DOM 状态同样关键。
- 加载的组件若带内联
<style></style>,多次加载会重复插入相同样式表,建议加id校验去重 - 用
<link rel="stylesheet" href="x.css" media="(prefers-color-scheme: dark)">比 JS 动态插入更轻量,且浏览器能跳过不匹配请求 - 组件卸载时,如果绑了全局事件(如
window.resize)、定时器、IntersectionObserver实例,必须显式清理,否则内存泄漏 - SPA 中路由反复进出同一页面,
data-module元素可能被复用,但模块实例未销毁——init 函数得自己判断是否已初始化
真正麻烦的不是怎么加载,而是加载之后谁负责清理、样式会不会冲突、脚本执行边界在哪、错误发生时用户看到什么。这些细节没对齐,按需加载反而变成性能负优化。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











