# 资源提示符
H5 中为我们提供了很多资源下载相关的 API,其中就有我们常用的资源提示符,用来控制资源的下载时机。
# 1、async
async 属性是用于 script 标签上的,使指定的资源异步下载,不阻塞浏览器的主线程。
<script rc="./index.js" async ></script>
如果没有加 async 标签的话,浏览器执行到这行语句就会开始下载 js 资源,主线程会等待资源的下载,等资源下载完成之后,执行下载的 js 文件,执行完成之后,才会去继续向下去解析 dom。
在这种情况下,浏览器的渲染主线程就会产生一段空闲的时间,也就是等待 js 下载的时间。很明显,这是不合理的。因为主线程明明后面还有很多事情要做,但是他却在阻塞起来等待 js 的下载。导致时间的利用率低下。
但是,如果加上了 async 提示符,浏览器就会通知网络线程去下载 js 文件,但是不会阻塞主线程了。主线程会继续向后解析,等 js 下载完成之后,再通知到主线程,主线程再转而执行这个 js 文件。
值得注意的是,使用了 async 的话,我们是不能精确控制 js 文件的执行时机的,js 文件的执行时机取决于他什么时候下载完成。下载完成之后就会通知主线程立即执行这个 js 文件。主线程此时可能正在解析 dom 中,亦或是已经解析完成了。所以我们无法控制这个资源的执行时间。
# 2、defer
defer 属性同样是用于 script 标签上的,使指定的资源异步下载,不阻塞浏览器的主线程。
<script rc="./index.js" defer ></script>
浏览器在解析 defer 修饰的 script 标签时,同样会通知网络线程下载文件,主线程继续执行。与 async 不同的是,当下载完成之后,js 文件不会立即,一定会等待主线程把 dom 元素全部解析完成之后再执行。
# 3、preload
preload 可以被用于任何资源的下载,同样是进行异步下载
<link rel="preload" href="./main.css" as="style">
当浏览器执行到这行代码时,同样会通知网络线程进行资源的下载,但是,下载完成之后不会立即执行资源,而是将资源缓存起来,等到需要的时候直接从缓存中读取。
preload 标识的资源下载优先级较高,即使当前浏览器已经有不少的下载任务了,依然会尽量优先处理 preload 的下载。
所以 preload 一般用于本页中需要用到的资源的下载。
# 4、prefetch
prefetch 可以被用于任何资源的下载,同样是进行异步下载
<link rel="prefetch" href="./main.css" as="satyle">
与 preload 一样,当浏览器执行到这行代码时,同样会通知网络线程进行资源的下载,但是,下载完成之后不会立即执行资源,而是将资源缓存起来,等到需要的时候直接从缓存中读取。
prefetch 标识的资源下载优先级较低,等到浏览器空闲的时候,才会执行 prefetch 的下载。
所以 prefetch 一般用于下载其他页面用到的资源。
# 5、DNS-prefetch
DNS-prefetch 用于实现 DNS 缓存。
<link rel="dns-prefetch" href="https://www.happyblog.com">
当我们的网页中添加了其他网站的链接,那么就可以使用 DNS-prefetch 去提前进行该网站的 DNS 解析。因为解析一个新的 DNS 也是需要时间的,我们可以在浏览器空闲的时候,提前进行 DNS 的解析,将解析结果缓存到本地。这样如果用户需要跳转该网站的话,可以提升响应速度。
# 6、总结
- async 和 defer 都是用于下载 js 文件的,可以使 js 文件异步下载,尽早下载(因为如果不加这两个资源提示符的话,我们一般是把 script 下载写在 html 最后面的。使用了这两个提示符,就可以把 script 写在 head 中,提早下载 js 文件了)。
- preload 和 prefetch 可以用于任何资源的异步下载,但是下载后不会立即执行。preload 的优先级较高,prefetch 的优先级较低,一般在浏览器空闲时执行。
- DNS-prefetch 用于提前进行 DNS 解析,并将解析结果缓存在本地。
← 浏览器中的事件循环 node模块查找策略 →