使用 可实现按需加载与模块化,但需注意路径必须带扩展名、避免滥用 async、HTTP/2 支持必要性及低版本浏览器兼容问题。

用 <script type="module"></script> 替代传统 <script></script> 能自动实现按需加载
浏览器对 <script type="module"></script> 的处理是异步且 defer 的——它不会阻塞 HTML 解析,也不依赖执行顺序,天然适合模块化组织。更重要的是,模块脚本默认启用 ES 模块作用域,支持 import 语法做静态分析,让构建工具或浏览器能识别真正用到的代码路径。
常见错误现象:直接把旧版 <script src="utils.js"></script> 改成 <script type="module" src="utils.js"></script> 后发现报错 Failed to resolve module specifier ——这是因为模块内 import 的路径必须带扩展名(如 .js)且不能省略协议或斜杠前缀。
- 相对路径必须写全:
import { helper } from './lib/helper.js'(.js不可省) - 不能写:
import { helper } from './lib/helper'或import { helper } from 'helper' - 顶层
await在模块中合法,可用于动态条件加载,但不建议在首屏关键路径滥用
import() 动态导入比静态 import 更适合延迟加载非首屏逻辑
静态 import 在解析阶段就发起所有依赖请求,哪怕某些模块只在用户点击后才用。而 import() 是 Promise-based 的运行时调用,配合事件监听可精准控制资源拉取时机。
使用场景举例:轮播图组件、表单校验规则、暗色模式切换器——这些功能不需要页面一打开就加载 JS。
立即学习“前端免费学习笔记(深入)”;
把任意文章或文档内容转换成精美的全屏翻页 HTML 演示文件(幻灯片风格)。当用户发来一篇文章、文档链接、Markdown 内容、或粘贴的文本,并且希望生成演示用的 HTML 时触发。支持任意内容来源:iWiki 链接、KM 链接、本地文件路径、直接粘贴的文本。生成的 HTML 文件保存到本地工作区,并通过企微直接发送给用户。触发词示例:帮我把这篇文章做成PPT、转成演示文档、生成HTML幻灯片、做个演示、转成可以演示的格式、article to deck、make a slide。
- 错误写法:
import { initCarousel } from './carousel.js'; initCarousel();(立即执行,白屏期多载入 80KB) - 正确做法:
button.addEventListener('click', () => import('./carousel.js').then(m => m.initCarousel())); - 注意:
import()返回 Promise,不能用在if外部作条件判断;也不能在模块顶层 await(除非用顶层 await,但兼容性需查)
HTML 中直接用 <script type="module"></script> + async 会破坏模块执行顺序
给模块脚本加 async 属性看似能“更快加载”,实则会让多个模块失去执行顺序保证。ES 模块规范要求同域下模块按 import 图谱拓扑排序执行,而 async 会把它降级为无序并发加载,可能引发 ReferenceError。
性能影响:虽然网络请求可能早几毫秒完成,但 JS 引擎要反复解析、编译、丢弃、重试,实际首屏可交互时间(TTI)反而更长。
- 避免:
<script type="module" async src="main.js"></script> - 推荐:
<script type="module" src="main.js"></script>(已自带 defer 行为) - 若真需要提前预取,改用
<link rel="modulepreload" href="main.js">,它不执行,只预加载并缓存
服务端不支持 HTTP/2 时,模块化反而增加请求数和延迟
每个 import 都是一个独立的 HTTP 请求。HTTP/2 的多路复用能摊平开销,但若服务器还跑在 HTTP/1.1 上,10 个模块 = 10 次 TCP 握手 + 队头阻塞风险,性能可能比合并成一个 bundle 还差。
容易被忽略的地方:本地开发用 http-server 或 Python http.server 默认都是 HTTP/1.1,测出的模块加载速度不具备生产参考价值。
- 上线前务必确认 CDN 或 Nginx 已启用 HTTP/2(检查响应头是否有
h2) - 对低版本浏览器(如 IE、旧版 Safari),仍需通过构建工具(Webpack/Vite)打包回传统 script
- 不要为了“模块化”而模块化——工具链没配好、部署环境不支持时,硬上
type="module"是给自己埋坑


















