资源提示符preload prefetch async defer

前言

在JavaScript中,资源提示符(Resource Hint)是一种使用<link>或<script>HTML标签来提示浏览器有关资源的方式。

我们正常开发中,对于这些接触不多,接下来了解一下。

1. 常用的资源提示符

以下是一些常见的资源提示符:

  • 指定资源的异步加载(Async):
xml 复制代码
<script src="script.js" async></script>
  • 指定资源的异步(Defer):
xml 复制代码
<script src="script.js" defer></script>
  • 预加载关键资源(Preload):
ini 复制代码
<link rel="preload" as="script" href="script.js">
  • 预解析关键资源(Prefetch):
ini 复制代码
<link rel="prefetch" as="script" href="script.js">
  • 预检查关键资源(Preconnect):
ini 复制代码
<link rel="preconnect" href="https://example.com">
  • 预检查关键资源(DNS-prefetch):
ini 复制代码
<link rel="dns-prefetch" href="https://example.com">

2. 案例说明

2.1 正常加载js

js的执行是自上而下,如果中间遇见资源加载,会中止dom解析,如下图所示:

案例:写一个index.html,写6千多个p标签,在标签前后分别打印p元素的个数。

index.html

html 复制代码
<script src="./index.js"></script>
<p></p>*6314个
<script src="./index.js"></script>

index.js

js 复制代码
console.log('打印***nodes', document.querySelectorAll('p'))

结果如图所示:

可以看到第一个打印为0,是因为dom没有开始解析,后面打印出全部是dom已经解析完成。

那么如何才能将script标签放在任意位置,加载js资源时,也不影响dom解析呢?接下来看看async。

2.2 使用async加载js

当在script标签中使用async,不会阻塞dom解析,当资源加载完成,会立刻执行。如下图所示:

案例:加上async,将script标签放在之前,看打印结果。

index.html

html 复制代码
<script src="./index.js"></script>
<script src="./index.js" async></script>
<p></p>*3000个
<script src="./index.js"></script>

结果如下:

可以放在任何位置,资源加载完成就运行。可以看到async打印的数量是不确定的。

问题是:资源加载完成,你直接运行,没办法控制dom解析了多少。

接下来看看defer如何解决。

2.3 defer加载js

使用defer是向浏览器表明,该脚本是要在文档被解析后,但在触发 DOMContentLoaded 事件之前执行的。

包含 defer 属性的脚本将阻塞 DOMContentLoaded 事件触发,直到脚本完成加载并执行。

案例:使用defer添加在标签之前,看打印结果。

html 复制代码
<script src="./index.js" defer></script>
<script src="./index.js" async></script>
<p></p>*3000个
<script src="./index.js"></script>

结果如下:

可以看到,js,等到dom解析执行之后,才执行

2.4 module解析

当script标签的设置为type="module",默认是defer进行解析。

案例:

html 复制代码
<script src="./index.js" type="module"></script>
<p></p>*3000个

结果如下:

可以看到是dom解析完成后才执行的。

2.5 preload、prefetch

prefetch

关键字 prefetch 作为元素 <link> 的属性 rel 的值,是为了提示浏览器,用户未来的浏览有可能需要加载目标资源,所以浏览器有可能通过事先获取和缓存对应资源,优化用户体验。

preload

指定页面很快就需要的资源,拿资源,不执行,只是安排脚本以更高的优先级进行下载和缓存。

使用 preload 的 rel 属性,将 <link> 标签转变成任何我们想要的资源的预加载器。还需要指定:

  • href 属性中的资源路径。
  • as 属性中的资源类型。

优先级

  • preload :直接去拿,优先级高
  • prefetch:优先级低,空闲拿

3. 总结

接下来总结一波:

  • async : 当在<script>标签中使用async属性时,该脚本将异步加载和执行,不会阻塞HTML解析器的进程。
  • defer : 与async类似,defer也允许脚本在HTML解析完成后执行,但不会阻塞解析。但与async不同,所有带有defer属性的脚本都会按照它们在HTML中出现的顺序并行加载,但在DOMContentLoaded事件触发前串行执行。
  • preload : <link rel="preload">允许开发者预加载页面未来可能需要的资源,如字体、图片或脚本。这些资源将在浏览器空闲时加载,并在需要时立即可用,从而提高了页面性能。
  • prefetch : <link rel="prefetch">则用于预取页面可能导航到的下一个页面的资源。这有助于在用户实际导航到该页面之前加载并缓存这些资源,从而减少页面加载时间。
  • Preconnect 和 DNS-Prefetch: 这两个资源提示符分别用于建立早期TCP连接和解析DNS,以加快未来HTTP请求的响应速度。

如有错误,请指正O^O!

相关推荐
Flynt1 小时前
axios 被投毒半年后,我把 npm 的"安全防线"实测了一遍:最信任的 SHA512 是安慰剂
前端·npm·node.js
excel2 小时前
Base62 和 Base64 有什么区别?
前端
风骏时光牛马3 小时前
大模型底层架构与AI源码深度剖析
前端
掘金挖土4 小时前
前端手摸手跑路之 AI 应用开发(九)
前端·后端
中文呀6 小时前
三维 GIS 离线缓存实战:逆向 CesiumOfflineCache,并亲手为它补上"自动更新"能力
前端
前进前进前进7 小时前
TRAE 全链路实战:做了一个警示牌一键生成器:纯 Canvas、单文件、零依赖
前端
小万7428 小时前
God‘s Eye View 深度解析:15 路公开信号 + CesiumJS 的浏览器级 OSINT 控制台,60 帧渲染的“真实间谍卫星模拟器”
前端
IT星宿8 小时前
浏览器标签页全是一个图标:我用名字哈希生成 favicon,让每个项目都有身份标识
前端
全栈项目管理程序猿8 小时前
ArcGIS JS 基础教程(32):体元系列 - VoxelSlice 体元切片
前端·javascript