在解析HTML的过程中,遇到需要加载的资源特点如下:
- CSS资源异步下载,下载和解析都不会阻塞构建dom树
<link href='./style.css' > rel='stylesheet'/>
- JS资源同步下载,下载和执行都会阻塞构建dom树
<script src='./index.js'/>
因为这样的特性,往往推荐将CSS样式表放在head头部,js文件放在body尾部,使得渲染能尽早开始。
CSS的加载
上文提到页面渲染是渲染进程的任务,这个渲染进程中又细分为GUI渲染线程和JS线程。
解析HTML生成DOM树,解析CSS生成样式表以及后面去生成布局树、图层树都是由GUI渲染线程去完成的,这个线程可以一边解析HTML,一边解析CSS,这两个是不会冲突的,所以也提倡把CSS在头部引入。
但是在JS线程执行时,GUI渲染线程没有办法去解析HTML,这是因为JS可以操作DOM,如果两者同时进行可能引起冲突。如果这时JS去修改了样式,那此时CSS的解析和JS的执行也没法同时进行了,会先等CSS解析完成,再去执行JS,最后再去解析HTML。
从这个角度来看,CSS有可能阻塞HTML的解析。
js脚本引入时async和defer有什么差别
预加载扫描器解决了JS同步加载阻塞HTML解析的问题,但是我们还没有解决JS执行阻塞HTML解析的问题。所有有了async和defer属性。
- 没有 defer 或 async,浏览器会立即加载并执行指定的脚本
- async 属性表示异步执行引入的 JavaScript,经加载好,就会开始执行
- defer 属性表示延迟到DOM解析完成,再执行引入的 JS
转载自:https://www.zhihu.com/question/61309490/answer/2391044776