?JS和CSS的加载会堵塞DOM的解析和渲染么?


image.png

这是我参与更文挑战的第13天,活动详情查看: 更文挑战


渲染流程图

首先,我们得先知道浏览器渲染的一个过程。如图

image-20210607152959714

可以看出主要是这么几个步骤。

  1. 解析HTML,构建DOM树

  2. 解析CSS,生成CSS规则树

  3. 合并DOM树和CSS规则,生成render树


问题 1:CSS会阻塞什么?

CSS 不会阻塞 DOM 的解析

很明显dom的解析和css的加载是并行的,毫无关联。

CSS 阻塞页面渲染

虽然css不会阻塞dom的解析,但是我们可以发现,我们的render需要结合cssom和dom。两者缺一不可。如果css没有加载完,就没有生成cssom,就没办法生成render。就不用谈什么渲染了。

CSS加载会阻塞后面js语句的执行

当CSS后边跟着嵌入的JS的时候,该CSS就会出现阻止后边资源下载的情况。

解决方法:把嵌入的JS放在CSS前边

原因:浏览器会维持html中css和js的顺序,样式表必须在嵌入放入JS执行前先加载、解析完,而嵌入的JS会阻塞后边的资源加载,所以就会出现CSS阻塞


问题2:JS会阻塞什么?

JS 阻塞 DOM 解析,但浏览器会”偷看”DOM,预先下载相关资源。

浏览器遇到 <script>且没有defer: 或async属性的 标签时,会触发页面渲染,因而如果前面CSS资源尚未加载完毕时,浏览器会等待它加载完毕在执行脚本

所有浏览器在下载JS的时候,会阻止其他的一切活动(比如其他资源的下载,内容的呈现等等)。为了提高用户体验,新一代浏览器都支持并行下载JS,但是JS下载还是会阻止其他资源如(图片、css文件等等)

原因:浏览器为了防止出现JS修改DOM树,需要重构DOM树的情况,就会阻止其他资源的下载和呈现

嵌入JS会阻止所有内容的呈现,但是外部JS只会阻止其后内容的显示

嵌入的JS应该放在什么位置
  1. 放在底部,只会阻塞所有内容的呈现,但是不会则阻塞资源的下载(js放在前)

  2. 如果嵌入JS放在head中,则嵌入JS放在css头部

  3. 使用defer(能延迟执行,等到整个文档解析完再执行,但是不会延迟下载,浏览器遇到script就立即下载脚本)

  4. 不要在嵌入的JS中调用执行时间较长的函数,如果一定要用,可以用setTimeout来调用

  5. 动态脚本元素使用js动态创建HTML的几乎全部文档内容

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享