script标签中的async和defer属性

众所周知,html中的script标签都是同步按顺序来执行的,并且在加载和执行的时候会中断DOM解析器的解析过程,下面列举一个简单的例子来观察这一过程:


loadjs.html代码:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Load Script</title>
</head>
<body>
<h1>Load javascript testing</h1>
<script type="text/javascript" src="./js/a.js" ></script>
<script type="text/javascript" src="./js/b.js" ></script>
<h2>defer & async</h2>
</body>
</html>
这里为了有利于观察,在加载a.js这个文件时后台服务会增加一个延迟5s的响应时间


页面显示效果一:

我们可以看到页面先显示"Load javascript testing", 等待5秒之后才显示"defer & async",很显然,加载和执行js脚本确实中断了DOM的解析和渲染。

html5中script标签支持async和defer属性,这两个属性是做什么的呢,查看w3c文档你可以知道如果script标签有async或者defer属性,那么加载和执行脚本将不会block DOM的解析和渲染,眼见为实:

修改loadjs.html代码:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Load Script</title>
</head>
<body>
<h1>Load javascript testing</h1>
<script type="text/javascript" src="./js/a.js" async></script>
<script type="text/javascript" src="./js/b.js" async></script>
<h2>defer & async</h2>
</body>
</html>

页面显示效果二:


页面是渲染不会受js脚本的影响而同时显示"Load javascript testing"和"defer & async"。


async和defer有什么区别呢,两者最重要的区别是什么时候去执行脚本:

Both async and defer scripts begin to download immediately without pausing the parser and both support an optional onload handler to address the common need to perform initialization which depends on the script. The difference between async and defer centers around when the script is executed. Each async script executes at the first opportunity after it is finished downloading and before the window’s load event. This means it’s possible (and likely) that async scripts are not executed in the order in which they occur in the page. The defer scripts, on the other hand, are guaranteed to be executed in the order they occur in the page. That execution starts after parsing is completely finished, but before the document’s DOMContentLoaded event.

loadjs.html:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Load Script</title>
<link rel="stylesheet" href="./style/jquery-ui.css">
</head>
<body>
<h1>Load javascript testing</h1>
<script type="text/javascript" src="./js/a.js" async></script>
<script type="text/javascript" src="./js/b.js" async></script>
<h2>defer & async</h2>
</body>
</html>

a.js内容:

var globalA = 'globalA';
var globalFunction = function(){
    return 'I am global function created in a.js';
};


b.js内容:

var globalB = 'globalB';
console.log(globalFunction());

结果:在执行
console.log(globalFunction());
时抛出异常:<span style="font-family: Arial, Helvetica, sans-serif;">Uncaught ReferenceError: globalFunction is not defined,如果就async改成defer,将不会抛出此异常</span>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值