DOMContentLoaded与异步脚本async
只要html解析完,就会触发DOMContentLoaded
<scirpt async src='xxx'>
-
情况一: async脚本加载完,HTML还未解析完
-
情况二: async还没有加载完,HTML就已经解析完毕
总结:
1、无论情况1,还是情况2,DOMContentLoaded都是在html解析完就执行
2、async异步加载的js资源,不会阻塞DOM的解析
这里会单独开启一个网络线程去下载js资源,而且下载资源也是并行的
A: <scirpt async src='src1'>
B:<scirpt async src='src2'>
A和B会同时下载
3、一旦js资源下载完毕,就会立马去执行,所以 并行下载的js资源不能保证按照先后顺序执行
A: <scirpt async src='src1'>
B:<scirpt async src='src2'>
A和B会同时下载,
但是B的js代码可能会比A先执行,所以二者js代码最好不要依赖
4 因为async异步加载js代码,所以js代码最好不要操作DOM,因为有可能js下载完执行去操作DOM而此时的DOM还未解析到,不存在
DOMContentLoaded与延迟脚本defer
DOMContentLoaded是在defer脚本执行完以后才触发(async是在dom解析完就触发DOMContentLoaded
- 情况一,HTML未解析完,defer已经加载完
- 情况二,HTML解析完,defer还未加载完
总结
1 无论HTML解析完没,都得等defer的脚本加载完,并且执行完才会触发DOMContentLoaded
2 defer的脚本,必须在html解析完以后才会去执行,而不是像async脚本一旦加载完就立马执行
所以defer立马可以随意操作DOM,因为执行的时候DOM全部都解析完毕
而且传入的延迟脚本会按照顺序执行
A: <scirpt defer='defer' src='xx'>
B: <scirpt defer='defer' src='xx'>
现实情况:
1、A和B并不一定会按照先后顺序执行
2、A和B并不一定在DOMContentLoaded前执行,所以最好只包含一个
无论是defer还是async他们都是异步加载
目的:不阻塞页面解析
同步加载脚
解析HTML的时候,遇到同步脚本
<scirpt src='src1'>
会先将脚本下载完,然后立马执行完脚本,才会继续向下解析HTML
思考,css加载和js加载是否会阻塞页面解析?
外链css
- 外链css是并行下载,不会阻碍其他资源下载,不会阻碍页面解析,但是会阻碍屏幕渲染
< link type ="text/css" href ="http://69.64.92.205/test.css" />
< img src ="http://www.pic.com/pic1.jpg" />
<h1>test</h1>
<script src='http:test.com/jquery.js'/>
< img src ="http://www.pic.com/pic2.jpg" />
<h2>test</h2>
1、css和图片会并行下载,jquery.js也会下载
2、并且会继续向下解析DOM元素h1
3、但是此时页面不会显示h1标签的内容
因为只有dom tree 和 cssdom合成render tree才会显示,而cssdom需要等带外链css下载完才行
4、如果jquery.js代码下载好了,而外链css资源没下载完,js代码也不会执行
因为js代码有可能会操作DOM的css属性,此时
5 、 jquer.js代码未执行完以前,不会继续往下解析HTML,即不会去下载pic2,也不会去解析h2
因为js代码可能会操作DOM,如果此时显示h2,然后js代码下载完毕后执行时又要删除h2这个DOM
那么就要引起页面回流,浪费性能,所以必须等js代码下载完毕且执行完才会继续往下解析HTMl
缺点:
如果下载js代码时间过长,页面就阻塞在这里
所以有了异步和延迟加载脚本