rel=模块预加载

modulepreload 关键字针对 <link> 元素的 rel 属性,提供了一种声明性方式来抢先获取 模块脚本、解析和编译它,并将其存储在文档的模块映射中以供以后执行。

¥The modulepreload keyword, for the rel attribute of the <link> element, provides a declarative way to preemptively fetch a module script, parse and compile it, and store it in the document's module map for later execution.

预加载允许提前下载模块及其依赖,并且还可以显着减少总体下载和处理时间。这是因为它允许页面并行获取模块,而不是在处理每个模块并发现其依赖时按顺序获取模块。但请注意,你不能只预加载所有内容!你选择预加载的内容必须与其他可能会缺乏资源的操作进行平衡,从而对用户体验产生不利影响。

¥Preloading allows modules and their dependencies to be downloaded early, and can also significantly reduce the overall download and processing time. This is because it allows pages to fetch modules in parallel, instead of sequentially as each module is processed and its dependencies are discovered. Note however that you can't just preload everything! What you choose to preload must be balanced against other operations that might then be starved, adversely affecting user experience.

rel="modulepreload" 的链接与与 rel="preload" 的链接类似。主要区别在于,preload 只是下载文件并将其存储在缓存中,而 modulepreload 获取模块,解析并编译它,并将结果放入模块映射中,以便准备执行。

¥Links with rel="modulepreload" are similar to those with rel="preload". The main difference is that preload just downloads the file and stores it in the cache, while modulepreload gets the module, parses and compiles it, and puts the results into the module map so that it is ready to execute.

使用 modulepreload 时,获取请求模式始终为 cors,并且 crossorigin 属性用于确定请求 凭证模式。如果 crossorigin 设置为 anonymous""(默认),则凭证模式为 same-origin,并且仅针对使用 same-origin 的请求发送 Cookie 和身份验证等用户凭证。如果 crossorigin 设置为 use-credentials,则凭据模式为 include,并且单源和跨源请求的用户凭据都为 include

¥When using modulepreload the fetch request mode is always cors, and the crossorigin property is used to determine the request credential mode. If crossorigin is set to anonymous or "" (default), then the credentials mode is same-origin, and user credentials such as cookies and authentication are only sent for requests with the same-origin. If crossorigin is set to use-credentials then the credentials mode is include, and user credentials for both single- and cross-origin requests.

对于带有 rel="modulepreload" 的链接,as 属性是可选的,默认为 "script"。它可以设置为 "script" 或任何类似脚本的目标,例如 "audioworklet""paintworklet""serviceworker""sharedworker""worker"。如果使用任何其他目标,则会在元素上触发名为 "error" 的 Event

¥The as attribute is optional for links with rel="modulepreload", and defaults to "script". It can be set to "script" or any script-like destination, such as "audioworklet", "paintworklet", "serviceworker", "sharedworker", or "worker". An Event named "error" is fired on the element if any other destination is used.

浏览器还可以另外选择自动获取模块资源的任何依赖。但请注意,这是特定于浏览器的优化 - 确保所有浏览器都尝试预加载模块依赖的唯一方法是单独指定它们!此外,名为 loaderror 的事件在加载指定资源成功或失败后立即触发。如果自动获取依赖,则主线程中不会触发任何其他事件(尽管你可能会监视服务工作线程或服务器上的其他请求)。

¥A browser may additionally also choose to automatically fetch any dependencies of the module resource. Note however that this is a browser-specific optimization — the only approach to ensure that all browsers will try to preload a module's dependencies is to individually specify them! Further, the events named load or error fire immediately following success or failure of loading the specified resources. If dependencies are automatically fetched, no additional events are fired in the main thread (although you might monitor additional requests in a service worker or on the server).

示例

¥Examples

考虑 JavaScript 模块 指南中介绍的 basic-modules 示例 (现场版)。

¥Consider the basic-modules example (live version), introduced in the JavaScript modules guide.

它具有如下所示的文件结构,由顶层模块 main.js 组成,该模块使用 import 声明 静态导入两个依赖模块 modules/canvas.jsmodules/square.js

¥This has a file structure as shown below, consisting of the top level module main.js, which statically imports two dependency modules modules/canvas.js and modules/square.js using the import statement.

index.html
main.js
modules/
    canvas.js
    square.js

下面示例的 HTML 显示了如何在 <script> 元素中获取 main.js。只有在 main.js 加载之后,浏览器才会发现并获取这两个依赖模块。

¥The HTML for the example below shows how main.js is fetched in a <script> element. Only after main.js has loaded does the browser discover and fetch the two dependency modules.

html
<!doctype html>
<html lang="en-US">
  <head>
    <meta charset="utf-8" />
    <title>Basic JavaScript module example</title>
    <style>
      canvas {
        border: 1px solid black;
      }
    </style>
    <script type="module" src="main.js"></script>
  </head>
  <body></body>
</html>

下面的 HTML 更新了示例,为主文件和每个依赖模块使用 <link> 元素和 rel="modulepreload"。这要快得多,因为三个模块在需要之前都开始异步并行下载。当 main.js 被解析并且其依赖已知时,它们已经被获取和下载。

¥The HTML below updates the example to use <link> elements with rel="modulepreload" for the main file and each of the dependency modules. This is much faster because the three modules all start downloading asynchronously and in parallel before they are needed. By the time main.js has been parsed and its dependencies are known, they have already been fetched and downloaded.

html
<!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" />
    <style>
      canvas {
        border: 1px solid black;
      }
    </style>

    <script type="module" src="main.js"></script>
  </head>
  <body></body>
</html>

规范

Specification
HTML Standard
# link-type-modulepreload

¥Specifications

浏览器兼容性

BCD tables only load in the browser

¥Browser compatibility

也可以看看

¥See also

  • 投机加载 用于与 <link rel="modulepreload"> 和其他类似性能改进功能进行比较。
  • 预加载模块(developer.chrome.com)