html中script标签中,async/defer 属性的作用和区别(有图片辅助理解)

在这里插入图片描述

一. HTML是怎样被解析的?html中script标签中,async/defer 属性的作用和区别(有图片辅助理解)_第1张图片

见上图,HTMl文件被浏览器下载下来后,浏览器会从文件开始处解析我们的html文件,并一路解析知道文件的末尾最后一行结束,在解析的过程中,如果它遇到了诸如img标签,需要下载外部资源的情况时, 浏览器会发送下载的请求,然后会继续解析下去,即使外部资源还没有完全下载完毕,这个下载的操作是在后台执行的,


html中script标签中,async/defer 属性的作用和区别(有图片辅助理解)_第2张图片

但是,如果当我们遇到了JavaScript文件(一个 script 标签), 它会触发一个请求去下载那个指向的JavaScript文件,并且同时,HTMl解析器(parser)会停止 ,并且开始等待,直到JavaScript文件下载完毕,并且执行完毕之后,才会继续向下进行解析

读到这里有的人可能会想说,平时见到的课程教授方法都是告诉让把script都放到body标签的末尾部分啊,没有写到header里的啊。

是的!这么做的目的就是为了让类似于图片等其他的html内容都先被解析完毕,最后再处理解析这个script标签内对应的js文件,下载之后再执行,这样,如果js文件中涉及到取DOM节点等操作时就不会出错,因为基础结构都已经解析完毕了,都存在,否则的话,script标签放在header里面,这时候还没有解析到下面的html body标签里面的内容,这时候操作DOM,就会出错。

好啦说了这么多,是时候进入正题!介绍script标签里面的async和defer属性了!

二. script标签中各属性的作用

1. 没有属性

html中script标签中,async/defer 属性的作用和区别(有图片辅助理解)_第3张图片
绿色(解析/parsing)停止的地方就是碰到script标签的地方,js文件下载完,执行之后,html文件才再次继续进行解析;

问题在于,如果js文件比较大,这样会极大的阻碍网页页面的生成,页面出于短暂长时间空白,看起来页面像是卡在了那里,这种情况是我们需要极力避免的。

2. async

html中script标签中,async/defer 属性的作用和区别(有图片辅助理解)_第4张图片
async 属性告诉我们HTML解析器(parser),它可以在后台下载这个JS文件,并且它可以继续向下解析当js文件在后台下载的时候,之后,只要js文件一下载完毕,这个时候如果解析工作还没有完成,还在解析, 那么立马停下手头的解析工作,开始执行js文件,执行完之后,再恢复解析工作,继续向下解析;如果此时解析完了,那就更不用说了,直接开始执行js文件。

问题在于,如果你header里面有多个script标签,肯定从上到下有个顺序吧,如果彼此互相没有依赖都能独立执行,那还好说,如果存在依赖关系,那么此刻先执行哪个文件,后执行哪个文件是有要求的时候,那么我们就没办法控制,因为哪个文件先执行,完全取决于哪个文件先下载完毕,先下载完毕的就先执行,后下载完毕的就后执行,所以不可避免的就会乱序执行起来。

3. defer

html中script标签中,async/defer 属性的作用和区别(有图片辅助理解)_第5张图片
defer 属性和async有点像,async是js文件刚下载完毕就开始执行,而defer是等待 HTML的解析所有都完毕之后,才会进行js文件的执行,并且这个js文件的执行是按照script标签定义的顺序来执行的,所以这就和在body中的最末尾定义普通没有任何属性的多个script标签一样,从上到下按顺序开始执行,并且没有阻塞HTML文件的解析,所以defer这个属性的添加,完美的解决了async的问题,还有没有属性却还定义在header中script标签,阻塞html文件解析的情况。

** Plus:重要!必看!**
html中script标签中,async/defer 属性的作用和区别(有图片辅助理解)_第6张图片
html中script标签中,async/defer 属性的作用和区别(有图片辅助理解)_第7张图片

From the official specification:
“For classic scripts, if the async attribute is present, then the classic script will be fetched in parallel to parsing and evaluated as soon as it is available (potentially before parsing completes) . If the async attribute is not present but the defer attribute is present, then the classic script will be fetched in parallel and evaluated when the page has finished parsing. If neither attribute is present, then the script is fetched and evaluated immediately, blocking parsing until these are both complete.”
html中script标签中,async/defer 属性的作用和区别(有图片辅助理解)_第8张图片

参考资料:

HTML Living Standard — Last Updated 14 September 2021

视频: What Is The Fastest Way To Load JavaScript

JavaScript高级程序设计(第四版)

你可能感兴趣的:(复习学习日记,前端JS面试题,html5,html,javascript)