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

HTML5的async和deferred属性的出现对于页面的初次渲染来说是一个福音,解决了加载js文件时的阻塞问题,实现了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的 defer 属性.因为当defer脚本下载的时候,其他操作可以并行执行,所以大概快了1秒:

哪些浏览器支持async 和 defer?

除了基于Webkit的新版本浏览器,FireFox已经支持defer和onload属性很长时间了,而且从FF3.6开始添加了async属性。IE同样支持defer属性,但还不支持async属性,从IE9开始,onload属性也将被支持。

看到webkit实现async我开心得合不拢嘴了。对每个网站来说,阻塞都是一个巨大的性能瓶颈,而可以直接指定script文件异步加载无疑会加快web页面的速度,大大提高用户等待网页的体验度。

时间: 2024-12-16 20:33:49

HTML5 <script>元素async,defer异步加载的相关文章

HTML &lt;script&gt;元素async,defer异步加载

先来试个一句话解释仨,当浏览器碰到 script 脚本的时候: <script src="script.js"></script> 没有 defer 或 async,浏览器会立即加载并执行指定的脚本,“立即”指的是在渲染该 script 标签之下的文档元素之前,也就是说不等待后续载入的文档元素,读到就加载并执行. <script async src="script.js"></script> 有 async,加载和渲染

使用async属性异步加载执行JavaScript

HTML5让我兴奋的一个最大的原因是,它里面实现的新功能和新特征都是我们长久以来一直期待的.比如,我以前一直在使用placeholders,但以前必须要用JavaScript实现.而HTML5里给JavaScript标记提供的async属性,使JavaScript能异步加载执行.之前我需要各种的JavaScript插件来实现这种功能,但现在这个新属性能让我们轻松的实现异步加载. async – HTML代码 真的非常简单,就像下面这样: <script async src="siteScr

script 异步加载 async 和 defer的区别

在HTML被解析的时候,如果遇到 <script> 标签,就会先暂停HTML解析,立即执行脚本(非外部js文件).<script src="./1.js"> 引入的外部js文件情况下会先下载再执行. 所以,如果在HTML解析期间被执行 js 脚本且计算量很大的情况下(循环十万次),那么页面就会造成卡顿和白屏现象. 这也是为什么 <script> 脚本建议写在 <body></body> 标签内的最后面,就是为了加快 HTML

JSON、异步加载、时间线

JSON(其实他就是一个对象,但是和对象唯一不同的地方在与,我们常常在对象里给属性名不加双引号,但是,json必须给属性名加双引号) json是一种传输数据的格式 对象(属性名加不加双引号都行) var ob = { name:"yang", age:25; height:123 } json(属性名必须加双引号) var ob = { "name":"yang", "age":25; "height":1

高性能网站优化-确保异步加载脚本时保持执行顺序

<高性能网站建设进阶指南> 脚本如果按照常规方式加载,不仅会阻塞页面中其他内容的下载,还会阻塞脚本后面所有元素的渲染.异步加载脚本可以避免这种阻塞现象,从而提高页面加载速度.但是性能的提升是要付出代价的.代码的异步执行可能会出现竞争状态.简单地说就是页面内部的脚本需要的标示符如果是在外部文件中定义的,而当外部文件异步加载的时候,如果没有保证外部文件和内部脚本执行顺序,很有可能会出现未定义标示符的错误 当异步加载的外部脚本与行内脚本之间存在代码依赖时,就需要通过一种保证执行顺序的方法来整合这两个

ztree异步加载

Ztree异步加载的意思就是: 当点击展开树节点时,才去请求后台action返回点击节点的子节点数据并加载. 直接贴代码(SpringMvc+Mybatis): 前台页面ztreeList.jsp: <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <% String path = request.getContextPath(); Stri

百度地图 异步加载

API 1.1和1.2版本支持异步加载,您可以在引用脚本的时候添加callback参数,当脚本加载完成后callback函数会被立刻调用.请参考下面的使用示例: <!DOCTYPE html> <html><head><meta charset="utf-8"/><title>异步加载</title> <script type="text/javascript"> // 异步加载的方

spring mvc +HTML5实现移动端底部上滑异步加载更多内容分页效果

由于手机的携带的方便性和手机的越来越智能和移动网速越来越快,手机已经充斥着人们的生活.随着手机的流行, 移动应用也快速的火了起来比如微商城.手机网页.移动APP等等.既然移动应用这么火,我们今天来讲一下怎样实现在移 动网页中动态加载数据,那么我们怎么实现呢,是像pc网页那样,有个上一页和下一页还是其它的方式. 其实像pc网页那样上一页和下一页肯定不行的,手机屏幕很小,不好点击同时用户体验很差,今天来给大家介绍使用 spring mvc +HTML5实现移动端底部上滑异步加载更多内容分页效果的方式

Angular.js 与script.js 异步加载

<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>angular.js</title> <script type="text/javascript" src="./js/script.js"></script> <!--<script type="text/ja