浏览器渲染过程

浏览器渲染过程

  1. DOM 树:解析 HTML 构建 DOM(DOM 树)
  2. CSS 树:解析 CSS 构建 CSSOM(CSS 树)
  3. 渲染树:CSSOM 和 DOM 一起生成 Render Tree(渲染树)
  4. 布局(layout):根据Render Tree浏览器就知道网页中有哪些节点,以及各个节点与 CSS 的关系,从而知道每个节点的位置和几何属性(重排)
  5. 绘制(Paint):根据计算好的信息绘制整个页面(重绘)

过程如下图:
在这里插入图片描述

过程1、2、3非常快,但是4和5比较耗时

“重排” 和 “回流”是一个意思,指的是重新执行步骤4
“重绘” 指重新执行步骤5

浏览器的重绘与重排传送门

.

DOM 树 和 渲染树 的区别:

DOM 树与 HTML 标签一一对应,包括 head 和隐藏元素(display:none)
渲染树不包括 head 和隐藏元素(display:none),大段文本的每一个行都是独立节点,每一个节点都有对应的 css 属性


浏览器阻塞

自上而下解析HTML,逐渐构建起DOM tree,遇到style、link标签,会下载解析样式表,同时构建CSSOM tree,不会阻塞html的解析。但是遇到script标签,它会立即下载并执行得到的脚本,会阻塞HTML的解析。直到脚本里的同步代码部分(settimeout等异步操作之外的代码)执行完之后,再接着解析接下来的HTML。
直到将整个HTML文档的最后一个标签解析完毕,DOM tree生成完毕。然后CSSOM tree 、render tree生成,开始渲染。

1. js加载会阻塞DOM树的解析和渲染

如果把js放在页面顶部,下载和解析js的时间里面,dom迟迟得不到解析和渲染,浏览器一直处于白屏,所以把JavaScript文件放在页面底部更有利于页面快速呈现。

2. css加载不会阻塞DOM树的解析但会阻塞DOM树的渲染

如果把css文件引用放在HTML文档的底部,浏览器为了防止无样式内容闪烁,会在css文件下载并解析完毕之前什么都不显示,这也就会造成白屏现象。(但是在firefox浏览器中测试,会出现样式闪烁,这也算是不同浏览器的权衡吧,要么等css全解析完一起显示,要么先显示然后css解析完再重新画上新样式)

当css文件放在<head>中时,虽然css解析也会阻塞后续dom的渲染,但是在解析css的同时也在解析dom,所以等到css解析完毕就会逐步的渲染页面了。

3. css加载会阻塞后面js语句的执行

因此,为了避免让用户看到长时间的白屏时间,我们应该尽可能的提高css加载速度,比如可以使用以下几种方法:

  1. 使用CDN(因为CDN会根据你的网络状况,替你挑选最近的一个具有缓存内容的节点为你提供资源,因此可以减少加载时间)
  2. 对css进行压缩(可以用很多打包工具,比如webpack,gulp等,也可以通过开启gzip压缩)
  3. 合理的使用缓存(设置cache-control,expires,以及E-tag都是不错的,不过要注意一个问题,就是文件更新后,你要避免缓存而带来的影响。其中一个解决防范是在文件名字后面加一个版本号)
  4. 减少http请求数,将多个css文件合并,或者是干脆直接写成内联样式(内联样式的一个缺点就是不能缓存)

defer和async

js加载会阻塞DOM树的解析和渲染,但<script> 标签的async和defer属性可以改变阻塞HTML解析的情况(但是较低版浏览器不支持,所以最佳的实践是,将<script>放在</body>前)。

async和defer对于内联JavaScript是无效的

defer
设置了defer的script外链文件,在下载js文件期间不会阻塞HTML的解析,而且等js下载完毕时若HTML还没解析完毕,js会等到HTML文档解析完毕后再执行。如果有多个js下载文件,那么执行时也是按照顺序执行。

async
设置了async的script外链文件,在下载js文件期间不会阻塞HTML的解析,但是js下载完毕之后就会立即执行,无论现在HTML是否正在解析。
在这里插入图片描述x

posted @ 2022-07-20 18:15  猫老板的豆  阅读(26)  评论(0编辑  收藏  举报