rel="modulepreload"
modulepreload
关键字,用于 <link>
元素的 rel
属性,提供了一种声明式的方式来预取(preemptively fetch)一个模块脚本,对其进行解析和编译,并将其存储在文档的模块映射表中以供后续执行。
预加载(Preloading)允许模块及其依赖项提前下载,并且可以显著减少整体下载和处理时间。这是因为它可以让页面并行获取模块,而不是像每个模块被处理并发现其依赖项那样顺序获取。但请注意,你不能只是预加载所有内容!你选择预加载的内容必须与其他可能被饿死的(starved)操作相平衡,以免对用户体验产生不利影响。
带有 rel="modulepreload"
的链接与带有 rel="preload"
的链接类似。主要区别在于,preload
只是下载文件并将其存储在缓存中,而 modulepreload
会获取模块,对其进行解析和编译,并将结果放入模块映射表中,使其准备好执行。
使用 modulepreload
时,fetch 请求模式始终为 cors
,并且 crossorigin
属性用于确定请求的凭证模式。如果 crossorigin
设置为 anonymous
或 ""
(默认值),则凭证模式为 same-origin
,用户凭证(如 cookie 和身份验证)仅随 same-origin
请求发送。如果 crossorigin
设置为 use-credentials
,则凭证模式为 include
,并且会随同对同源和跨域请求发送用户凭证。
对于带有 rel="modulepreload"
的链接,as
属性是可选的,默认为 "script"
。它可以设置为 "script"
或任何类似脚本的目的地,例如 "audioworklet"
、"paintworklet"
、"serviceworker"
、"sharedworker"
或 "worker"
。如果使用了其他目的地,则会在元素上触发一个名为 "error" 的 Event
。
浏览器可能还会选择自动获取模块资源的任何依赖项。但请注意,这是浏览器特有的优化——确保所有浏览器都尝试预加载模块依赖项的唯一方法是单独指定它们!此外,名为 load
或 error
的事件会在指定资源加载成功或失败后立即触发。如果依赖项是自动获取的,主线程不会触发额外的事件(尽管你可能可以在 service worker 或服务器上监控额外的请求)。
示例
请考虑 basic-modules 示例(实时版本),该示例在 JavaScript 模块指南中已介绍。
它具有如下所示的文件结构,由顶层模块 main.js
组成,该模块使用 import
语句静态导入了两个依赖模块 modules/canvas.js
和 modules/square.js
。
index.html main.js modules/ canvas.js square.js
下面的示例 HTML 显示了 main.js
如何在一个 <script>
元素中获取。只有在 main.js
加载完成后,浏览器才会发现并获取两个依赖模块。
<!doctype html>
<html lang="en-US">
<head>
<meta charset="utf-8" />
<title>Basic JavaScript module example</title>
<script type="module" src="main.js"></script>
</head>
<body></body>
</html>
下面的 HTML 更新了示例,为主要文件和每个依赖模块使用了带有 rel="modulepreload"
的 <link>
元素。这要快得多,因为三个模块都在它们被需要之前异步且并行地开始下载。当 main.js
被解析并且其依赖项已知时,它们已经完成获取和下载。
<!doctype html>
<html lang="en-US">
<head>
<meta charset="utf-8" />
<title>Basic JavaScript module example</title>
<link rel="modulepreload" href="main.js" />
<link rel="modulepreload" href="modules/canvas.js" />
<link rel="modulepreload" href="modules/square.js" />
<script type="module" src="main.js"></script>
</head>
<body></body>
</html>
规范
规范 |
---|
HTML # link-type-modulepreload |
浏览器兼容性
加载中…
另见
- 推测性加载(Speculative loading),用于比较
<link rel="modulepreload">
和其他类似的性能改进功能。 - 在 web.dev 上预加载模块