script标签的defer 问题?

<script> 标签有 defer 和 async 属性,defer 属性标注的脚本会被异步下载但是不会被执行,直到文档的载入和解析完成,并可以操作,脚本才会被执行。这个异步下载是js主线程做的,还是页面渲染的线程做的?

阅读 3.7k
2 个回答

在浏览器中,JavaScript是单线程的,并且和UI渲染共用一个线程。

加个引用更有说服力,出自于最新版《深入浅出Nodejs》48页第三句。
我也看到有资料说,JavaScript线程和UI渲染都是浏览器线程,但因为它们互斥,所以只能串行。
不知道那种说法是正确的。

对于defer和anync的异步加载我也有疑惑,所以我查找到这个资料:

HTML5提出了Web Worker,它会在当前JavaScript的执行主线程中利用Worker类新开辟一个额外的线程来加载和运行特定的JavaScript文件,这个新的线程和JavaScript的主线程之间并不会互相影响和阻塞执行。

1: JS引擎线程和 UI[主]线程是互斥关系,而不是在同一个线程,具体可查询 线程互斥 的概念。

很显然的,js引擎大部分都以虚拟机的概念存在,不大可能跟上层应用公用线程。(个人猜测)

2: 在任何一种面向用户的程序设计里面,I/O 放在主线程同步都是一种无知的行为。
场景假设:

<img src="https://very_big_img_here.com"/>

如果浏览器的网络资源请求线程都安排在主线程,那 sry,你这张图片下载完成之前,浏览器是卡死的。
很显然现代浏览器都不这么二,所以,网络请求应该不是在 UI[主]线程。

3: <srcipt> 是HTML标准,在早期的时候,还有 JScriptVBScript等,而它配备的配置(属性)是标准里面定义用来告诉浏览器怎么处理这个标签的。

deferasync 属性都是告诉浏览器,这里面的内容你不要等待,你继续~;否则,浏览器默认情况是要等这里面的内容 下载 完成后转交给JS线程 执行 在继续往下解析。

4: WebComponent

5: 可以了解下客户端的知识,不要局限于纯前端,你提这问题,稍微有点客户端领域的知识的话,不看任何资料都能猜出个大该。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题