使用defer和async高效加载JavaScript

没有defer或async,在head

解析将暂停,直到获取并执行脚本为止。完成此操作后,解析将继续。

没有defer或async,在body末尾

解析是在没有任何停顿的情况下完成的,当它完成时,脚本会被fetched并执行。 解析是在脚本下载之前完成的,因此页面显示早于前面的示例。

使用async,在head

脚本是异步获取的,当它下载完,HTML解析会暂停以执行脚本,脚本执行完,再接着解析HTML。

使用defer,在head

脚本是异步获取的,当HTML解析完,再执行脚本。

"在head使用defer"和"在body末尾"都是在HTML解析完再执行脚本, 但"在head使用defer"比"在body末尾"执行脚本的时间要早,因为"在head使用defer"脚本是在HTML解析的同时下载的,而"在body末尾"脚本是在HTML解析完再下载的。

因此,就速度而言,这个是最优的方式。

阻塞解析

async会阻止页面的解析, defer不会。

阻塞渲染

async和defer都不能保证不阻塞渲染。这取决于你和你的脚本(例如,确保你的脚本在onLoad事件之后运行)。

domInteractive

标记为defer的脚本在domInteractive事件之后立即执行,该事件发生在加载、解析HTML和构建DOM之后。

此时,CSS和图像仍有待加载和解析。

完成此操作后,浏览器将发出domComplete事件,然后发出onLoad。

domInteractive之所以重要,是因为它的事件被认为是感知加载速度的衡量标准。

考虑到延迟的优点,在各种场景下,它似乎是比异步更好的选择。

另一个赞成用defer的原因

标记为async的脚本在可用时会按随意顺序执行。标记为defer的脚本将按标记中定义的顺序执行(在解析完成后)。

如下,有一个index.html文件,引入3个标记async的js文件和3个标记defer的js文件

js 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script src="./1.js" async></script>
    <script src="./2.js" async></script>
    <script src="./3.js" async></script>
    <script src="./11.js" defer></script>
    <script src="./12.js" defer></script>
    <script src="./13.js" defer></script>
</body>
</html>

2.js 和 12.js文件比较大,下载会慢一些

最终的执行顺序如下:

async和defer的区别

async和defer都是异步加载脚本,但async是加载完脚本后立即执行,而defer是在HTML解析完成后再执行脚本,也就是async会阻塞HTML的解析,defer不会阻塞。async和defer都不能保证不阻塞HTML的渲染。

标记为async的脚本在可用时会按随意顺序执行。标记为defer的脚本将按标记中定义的顺序执行(在解析完成后)。

参考英文原文

flaviocopes.com/javascript-...

相关推荐
aircrushin几秒前
Claude 5 之后,上下文工程该做减法了
前端·人工智能·后端
huabuyu2 分钟前
CLS 自动化归因及自愈:让系统自己定位根因、修复并验证
前端·javascript
用户6919026813394 分钟前
React 组件间通信全解析:从父子到跨级
前端·javascript
echoVic4 分钟前
同一个 bug,我在 WebGPU 渲染器里犯了两轮:一帧内多次写同一块 buffer
前端·webgl·图形学
胡萝卜术7 分钟前
数据主权与渲染防线:从受控组件到性能优化的完整图景
前端·javascript·面试
DFT计算杂谈8 分钟前
FeSe超薄膜在CaF2衬底上的电子结构DFT研究
java·服务器·前端
mONESY8 分钟前
React 组件通信进化史:从 Props 层层搬运到 Context 跨层级直达
javascript
BreezeJiang10 分钟前
父组件一更新,子组件就必须跟着更新吗?从 memo 走到 useCallback
前端·javascript
胡萝卜术11 分钟前
复用与并行:从自定义 Hooks 封装状态逻辑,到 Web Worker 的多线程计算
前端·javascript·面试
circuitsosk11 分钟前
长文本与高并发下的Token“瘦身”策略:Prompt压缩与上下文窗口优化
java·前端·python·prompt·上下文窗口·token优化