如上图,我们可以得到两个信息:
如果script标签内不带defer/async,那么浏览器在解析到script标签时会停止DOM的解析,一直等到script标签的加载与执行完成后,再进行之后的DOM解析。
如果添加defer标签,则script标签的加载不阻塞DOM加载,并在DOM加载完成后按照引入的顺序执行。
如果添加async标签,则script标签的加载也不阻塞DOM加载,但是在加载完之后立马执行,不能保证执行的顺序。
CSS的加载会阻塞JS的执行,进而阻塞DOM的解析。
- <head>
- <link rel="stylesheet" href="./style.css?sleep=3000"> // 假设css的加载会花3s
- <script src="./index.js"></script>
- </head>
- <body>
- <p>hello world</p>
- </body>
css和js同时加载,但是由于css未加载完毕,js代码不执行 -> 由于js代码还未执行,DOM元素不加载 -> 3秒后css加载完毕,js代码开始执行 -> js代码执行完毕,开始解析DOM
因为JS代码需要操作DOM,遇到script标签后,会先渲染一次标签之前的所有DOM,然后再加载和执行JS 。
- <body>
- <p id="box1">world</p>
- <script>
- console.log(document.getElementById('box1'));
- console.log(document.getElementById('box2'));
- </script>
- <p id="box2">hello</p>
- </body>
上述代码能获取到box1,但是无法获取到box2,因为js执行时box1已经解析和渲染,而box2还未解析和渲染。