Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(一)javascript高级程序设计: defer vs async #1

Open
6 tasks done
Quickeryi opened this issue Jun 5, 2017 · 2 comments
Open
6 tasks done

(一)javascript高级程序设计: defer vs async #1

Quickeryi opened this issue Jun 5, 2017 · 2 comments

Comments

@Quickeryi
Copy link
Owner

Quickeryi commented Jun 5, 2017

本文简单阐述一下<script>标签的defer & async两个属性

Defer:This Boolean attribute is set to indicate to a browser that the script is meant to be executed after the document has been parsed, but before firing DOMContentLoaded. The defer attribute should only be used on external scripts

Async:Set this Boolean attribute to indicate that the browser should, if possible, execute the script asynchronously. It has no effect on inline scripts
PS:support by HTML5

其实根据官方的定义,两个属性有着相同的作用:就是为了解决当加载脚本时页面渲染被阻塞,也就是常说的空白问题,只是async是HTML5提出的,当然两者还是有一些区别的

那么为何加载脚本会导致阻塞页面渲染呢,这里就不展开了,可以参考这篇文章:分析关键渲染路径性能

接下来详细的分析一下上述提到的两个属性

1.defer

  • 作用:对于这个属性值,我们先讨论另外一个问题,那就是在前端开发中我们始终遵循一个原则**外链的js文件放在文档的最底端,即</body>前面,其实这就是一种手动解决阻塞页面渲染的方式,那么defer的作用其实与这种手动的方式一样,即:如果一个script加了defer属性,即使放在head里面,它也会在html页面解析完毕之后再去执行,也就是类似于把这个script放在了页面底部**
  • 特性:1)js会按照引用顺序执行(ps:虽然官方这样说,但是不同的浏览器不一定是这样);2)所有js会在DOMContentLoaded事件前执行完毕
  • demo
<head>
   <meta charset="UTF-8">
   <title>Title</title>
   <script src="a.js" defer></script><!-- with defer -->
   <script src="b.js" defer></script><!-- with defer -->
</head>
//a.js: 大循环,执行会花费大量时间
for (var i = 0; i < 50000 ; i++) {
    console.log('a');
}
alert('a.js');

//b.js
alert('b.js');

结果分析
当加入defer属性时,DOMContentLoaded事件相对于loaded事件快1s左右触发,并且DOM会立刻渲染到页面上;而没有defer属性,两个事件前后相隔不超过10ms,且必须等待所有js解析执行完毕,才渲染DOM
with_defer
without_defer

  1. async
  • 作用:异步的加载和执行脚本
  • 特性:1) js一旦加载到就会立刻执行,所以当多个外链的js都使用了async时,它们不一定会按照引用的顺序执行,所以当各个引用有依赖关系时要慎用;2)所有js会在window.onload触发前执行
  • demo

结果分析
async也一样没有阻塞DOM渲染,并且效果看上去是非常棒
with_async

3.总结

这里引用别人一段话综述defer&async的相同和不同点吧
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
ps:需要注意的是,本人经过测试,发现即使使用defer,在chrome中依然无效,所以对于defer的种种特性,还是要具体看每一个浏览器环境的实现,但是async目前兼容性良好,在前端性能优化,特别是优化渲染路径,加快首屏渲染速度有极大的用处

@Quickeryi
Copy link
Owner Author

@Quickeryi
Copy link
Owner Author

补充一点:使用这两个属性的脚本中调用document.write方法会无效,换言之,不能使用document.write方法

@Quickeryi Quickeryi changed the title javascript高级程序设计: defer vs async (一)javascript高级程序设计: defer vs async Jun 9, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant