HTML5 <script>元素async,defer异步加载

本文介绍HTML5中的async与defer属性如何帮助实现脚本的异步加载,减少网页加载阻塞,提升页面加载速度。通过合理利用这些属性,开发者能够显著改善用户体验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文地址:HTML5′s async Script Attribute
原文日期: 2010年09月22日
翻译日期: 2013年08月22日

(译者注: 异步加载,可以理解为无阻塞并发处理.)

(译者再注: 建议使用 defer,但是经测试发现 defer 属性对页面内的script无效,没有时序差别.只对外部 js文件生效 )

我对于HTML5感到兴奋不已的原因之一是它实现了众多业界期待已久的特性。我们一直需要输入框显示空白提示,但都是用JavaScript来实现的。我们也想要整个块都变成可被点击,也是使用JavaScript来实现。
现在WebKit为HTML5实现了SCRIPT标签的async异步属性。过去我们使用各种JavaScript技巧来做这种事情,但现在新的属性让防止阻塞变得相对容易。

async - HTML属性

如我前面提到的,添加async属性非常简单:

<!-- 指定async,以及 onload 回调-->
<script async src="siteScript.js" onload="myInit()"></script>
事实上,如果你的JavaScript以及HTML结构设计的合理,那么90%的情况下你的Script元素可以使用异步加载。

defer - HTML属性
Safari 浏览器额外添加了defer属性
<!-- 指定defer,效果和async差不多-->
<script defer src="siteScript.js" onload="myInit()"></script>

async 与 defer 的差别
WebKit官方博客 很好地解释了async 与 defer 的不同

------------------------------------

正常情况下,当浏览器在解析HTML源文件时如果遇到外部的script,那么解析过程会暂停,并发送请求来下载script文件,只有script完全下载并执行后才会继续执行DOM解析。比如:
<script src="myBlockingScript.js"></script>
在下载过程中浏览器是被阻止做其他有用的工作的,包括 解析HTML,执行其他脚本,以及展示CSS布局。虽然Webkit预加载扫描程序可以探测性地在下载阶段进行多线程下载,但是某些页面仍然存在很大的网络延迟。
当前有很多技术来提升页面显示速度,但都需要额外的代码以及针对特定浏览器的技巧。现在,script可以通过添加async或者defer属性来让脚本不必同步执行,示例如下:

<script async src="myAsyncScript.js" onload="myInit()"></script>
<script defer src="myDeferScript.js" onload="myInit()"></script>
async 和 defer 标注的 script 都不会暂停HTML解析就立刻被下载,两者都支持onload事件回调来解决需要该脚本来执行的初始化。
两者的区别在于执行时的不同
async 脚本在script文件下载完成后会立即执行,并且其执行时间一定在 window的load事件触发之前。这意味着多个async脚本很可能不会按其在页面中的出现次序顺序执行。
与此相对,浏览器确保多个 defer 脚本按其在HTML页面中的出现顺序依次执行,且执行时机为DOM解析完成后,document的DOMContentLoaded 事件触发之前。

下面展示的是一个需要1秒来下载,以及1秒来解析执行其他操作的例子,我们可以看到整个页面载入花了大约2秒钟。
普通内联script执行时序


同样的例子,但这次我们指定了script的 defer 属性.因为当defer脚本下载的时候,其他操作可以并行执行,所以大概快了1倍。

使用defer异步加载的执行时序

------------------------------------

哪些浏览器支持async 和 defer
同样是上面引用的文章中提到:

除了基于Webkit的新版本浏览器,FireFox已经支持defer和onload属性很长时间了,而且从FF3.6开始添加了async属性。IE同样支持defer属性,但还不支持async属性,从IE9开始,onload属性也将被支持。
aynsc 棒极了!
看到webkit实现async我开心得合不拢嘴了。对每个网站来说,阻塞都是一个巨大的性能瓶颈,而可以直接指定script文件异步加载无疑会加快web页面的速度.


<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" /> <title>预览看板</title> </head> <link rel="stylesheet" href="./fixtures/css/preview.css?_<%= version %>"> <link rel="stylesheet" href="//kwesit.huawei.com/efinance/icp/xapp/material/view.css?_<%= version %>"> </link> <link rel="stylesheet" href="/efinance/icp/xapp/designer/finance.css?_<%= version %>"> </link> <link rel="stylesheet" href="//r-h2-beta.hw3static.com/s/uat/ffe/xcomponent/repository/lst/@ffe/fcore_aurora-vue2-saas@5.1.20-beta.2/build/lowcode/render/default/view.css"> </link> <body> <div id="ice-container"></div> <div id="new-loading"></div> <script> window.g_config = { locale: 'zh_CN', }; </script> <script src=" //r-h2-beta.hw3static.com/s/uat/fcore/resource/web/lst/@aurora/vue/3.22.8/runtime/lib/vue.min.js"></script> <script src="//r-h2-beta.hw3static.com/s/uat/fcore/resource/web/lst/@aurora/vue/3.22.8/runtime/lib/vue-composition-api.prod.js"> </script> <script src="//his-beta.huawei.com/aurora/webnova/runtime/lib/vue-i18n.min.js"></script> <script src="//r-h2-beta.hw3static.com/s/uat/fcore/resource/web/lst/@aurora/vue/3.22.8/runtime/lib/axios.min.js"> </script> <script src="//r-h2-beta.hw3static.com/s/uat/fcore/resource/web/lst/@aurora/vue/3.22.8/runtime/lib/aurora.min.js"> </script> <script src="//r-h2-beta.hw3static.com/s/uat/fcore/resource/web/lst/@aurora/vue/3.22.8/runtime/lib/aurora.service.min.js"> </script> <script src="//r-h2-beta.hw3static.com/s/uat/fcore/resource/web/lst/@aurora/vue/3.22.8/runtime/full/core.min.js"> </script> <script src="//r-h2-beta.hw3static.com/s/uat/fcore/resource/web/lst/@aurora/vue/3.22.8/runtime/full/base.min.js"> </script> <script src="/efinance/icp/xapp/designer/fixtures/lowcode-egine-alicdn/prop-types.min.js"></script> <script src="/efinance/icp/xapp/designer/fixtures/lowcode-egine-alicdn/react.production.min.js"></script> <script src="/efinance/icp/xapp/designer/fixtures/lowcode-egine-alicdn/react-dom.production.min.js"></script> <script src="/efinance/icp/xapp/designer/fixtures/lowcode-egine-alicdn/lodash.min.js"></script> <script crossorigin="anonymous" src="/efinance/icp/xapp/designer/fixtures/lowcode-egine-alicdn/vue-renderer.js"></script> <script src="//kwesit.huawei.com/efinance/icp/xapp/material/meta.js?_<%= version %>"></script> <script src="//kwesit.huawei.com/efinance/icp/xapp/material/view.js?_<%= version %>"></script> <script src="//r-h2-beta.hw3static.com/s/uat/ffe/xcomponent/repository/lst/@ffe/fcore_aurora-vue2-saas@5.1.20-beta.2/build/lowcode/render/default/view.js"></script> <script type="text/javascript" src="./js/preview.js?_<%= version %>"></script> </body> </html> 上面的代码改成下面的,算是优化提升吗? <!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" /> <title>预览看板</title> </head> <link rel="stylesheet" href="./fixtures/css/preview.css?_<%= version %>"> <link rel="stylesheet" href="//kwesit.huawei.com/efinance/icp/xapp/material/view.css?_<%= version %>"> </link> <link rel="stylesheet" href="/efinance/icp/xapp/designer/finance.css?_<%= version %>"> </link> <link rel="stylesheet" href="//r-h2-beta.hw3static.com/s/uat/ffe/xcomponent/repository/lst/@ffe/fcore_aurora-vue2-saas@5.1.20-beta.2/build/lowcode/render/default/view.css"> </link> <body> <div id="ice-container"></div> <div id="new-loading"></div> <script> window.g_config = { locale: 'zh_CN', }; </script> <script defer src=" //r-h2-beta.hw3static.com/s/uat/fcore/resource/web/lst/@aurora/vue/3.22.8/runtime/lib/vue.min.js"></script> <script defer src="//r-h2-beta.hw3static.com/s/uat/fcore/resource/web/lst/@aurora/vue/3.22.8/runtime/lib/vue-composition-api.prod.js"> </script> <script defer src="//his-beta.huawei.com/aurora/webnova/runtime/lib/vue-i18n.min.js"></script> <script defer src="//r-h2-beta.hw3static.com/s/uat/fcore/resource/web/lst/@aurora/vue/3.22.8/runtime/lib/axios.min.js"> </script> <script defer src="//r-h2-beta.hw3static.com/s/uat/fcore/resource/web/lst/@aurora/vue/3.22.8/runtime/lib/aurora.min.js"> </script> <script defer src="//r-h2-beta.hw3static.com/s/uat/fcore/resource/web/lst/@aurora/vue/3.22.8/runtime/lib/aurora.service.min.js"> </script> <script defer src="//r-h2-beta.hw3static.com/s/uat/fcore/resource/web/lst/@aurora/vue/3.22.8/runtime/full/core.min.js"> </script> <script defer src="//r-h2-beta.hw3static.com/s/uat/fcore/resource/web/lst/@aurora/vue/3.22.8/runtime/full/base.min.js"> </script> <script defer src="/efinance/icp/xapp/designer/fixtures/lowcode-egine-alicdn/prop-types.min.js"></script> <script defer src="/efinance/icp/xapp/designer/fixtures/lowcode-egine-alicdn/react.production.min.js"></script> <script defer src="/efinance/icp/xapp/designer/fixtures/lowcode-egine-alicdn/react-dom.production.min.js"></script> <script defer src="/efinance/icp/xapp/designer/fixtures/lowcode-egine-alicdn/lodash.min.js"></script> <script crossorigin="anonymous" defer src="/efinance/icp/xapp/designer/fixtures/lowcode-egine-alicdn/vue-renderer.js"></script> <script defer src="//kwesit.huawei.com/efinance/icp/xapp/material/meta.js?_<%= version %>"></script> <script defer src="//kwesit.huawei.com/efinance/icp/xapp/material/view.js?_<%= version %>"></script> <script defer src="//r-h2-beta.hw3static.com/s/uat/ffe/xcomponent/repository/lst/@ffe/fcore_aurora-vue2-saas@5.1.20-beta.2/build/lowcode/render/default/view.js"></script> <script type="text/javascript" defer src="./js/preview.js?_<%= version %>"></script> </body> </html> 大概能提升多少?
最新发布
06-24
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值