modulepreload 是 <link rel="modulepreload"> 用于预获取模块而不执行,区别于 <script type="module"> 的立即解析执行;它需绝对路径、as="script",且服务端需配 CORS,适用于明确依赖链或动态导入前的预加载。

什么是 modulepreload,它和 script type="module" 有什么区别?
modulepreload 是一个 <link> 标签的 rel 值,专门用于提前获取(fetch)但不执行 ES 模块及其依赖。它不触发模块解析、求值或副作用,只把脚本及其 import 链下载到浏览器缓存中。
关键区别在于:
-
<script type="module" src="a.js"></script>会立即 fetch + parse + evaluate -
<link rel="modulepreload" href="a.js">只 fetch,等后续真正 import 时才解析执行
这能避免重复请求,也能让深层依赖提前进缓存,减少“瀑布式加载”。
怎么写有效的 modulepreload 标签?
必须满足三个条件,缺一不可:
立即学习“前端免费学习笔记(深入)”;
- 使用
<link rel="modulepreload">,不能用<script>或其他rel - 必须指定
href,且路径需与后续import()或静态import中的路径完全一致(包括协议、域名、查询参数) - 推荐加上
as="script",否则浏览器可能按默认类型(如fetch)处理,影响优先级和 CORS 策略
<link rel="modulepreload" href="/js/utils.js" as="script"> <link rel="modulepreload" href="/node_modules/lodash-es/index.js" as="script">
注意:不支持 crossorigin 属性直接写在 <link> 上;如果模块是跨域的,必须确保服务端返回正确的 Access-Control-Allow-Origin,否则 preload 会静默失败(控制台无报错,但后续 import 报 CORS 错误)。
将 Markdown 文章转换为微信公众号兼容的纯 HTML 格式。当用户要求"转成微信格式"、"生成公众号文章 HTML"、"排版到微信草稿箱"、"微信粘贴格式"时触发。输出带内联样式的纯 HTML,微信编辑器可直接渲染,无需额外适配。支持标题、段落、列表、粗体、行内代码、表格、引用块、代码块、配图的完整转换。
哪些场景下用 modulepreload 才真有用?
它不是“所有模块都加一遍”就有收益,适用场景很具体:
- 主模块(entry)明确依赖的深层模块,比如
main.js静态 import 了./features/chart.js,而chart.js又 import 了./lib/d3.js—— 可以提前 preloadd3.js - 动态
import()的目标模块,尤其是用户操作前就预判要加载的(如点击“编辑”前 preloadeditor.js) - 多个入口共用的大型工具模块(如自研 UI 组件库),在 HTML head 中统一 preload,避免各入口重复 fetch
不推荐:
- 对尚未确定是否会被执行的模块盲目 preload(浪费带宽)
- preload 未经过构建工具处理的原始源码(如
.ts文件)—— 浏览器不识别 - 在模块路径含哈希但 HTML 未同步更新时硬编码(会导致 404 或加载旧版本)
常见错误和调试方法
最常遇到的问题是“写了没效果”或“preload 后 import 还是卡顿”,原因多为:
- 路径不一致:HTML 里写
href="./utils.js",但代码里写import './utils.js'(相对路径解析上下文不同)→ 改成绝对路径更稳,如/js/utils.js - 缺少
as="script":Chrome 会降级为普通 fetch,不参与模块图预加载,Network 面板里看到 Priority 是 “Low” 而非 “High” - 模块本身有动态 import,但只 preload 了第一层 → 需要手动展开依赖树,或用构建工具(如 Rollup/Vite 插件)自动生成完整 preload 列表
- 开发环境启用了 HTTP/2 Server Push 或本地代理重写,干扰了 preload 行为 → 用无痕模式 + 禁用缓存复现真实行为
检查是否生效,打开 Chrome DevTools → Network → 刷新页面,筛选 Initiator 列为 Preload 的请求,确认状态码是 200 且没有被 cancel。
实际项目里,手工维护 modulepreload 很容易脱节;真正稳定的方案是让打包工具在生成 HTML 时自动注入,而不是靠人眼对齐路径。


















