浏览器页面渲染流程

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/b954960630/article/details/82317999

浏览器渲染流程如下图所示:
这里写图片描述
大概可以划分成以下几个步骤:

  • (1)解析HTML文件,构建 DOM Tree
  • (2)解析CSS,构建 CSSOM Tree(CSS规则树)
  • (3)将 DOM Tree 和 CSSOM Tree合并,构建Render tree(渲染树)
  • (4)reflow(重排):根据Render tree进行节点信息计算(Layout)
  • (5)repaint(重绘):根据计算好的信息绘制整个页面(Painting)

理论上,每一次的dom更改或者css几何属性更改,都会引起一次浏览器的重排/重绘过程,而如果是css的非几何属性更改,则只会引起重绘过程。所以说重排一定会引起重绘,而重绘不一定会引起重排


一、构建Render tree

这里写图片描述
Render tree是由 DOM 和 CSSOM 组合构建而成的。也是页面可视化元素按照其显示顺序而组成的树。它的作用是让浏览器按照正确的顺序绘制内容。

非可视化的 DOM 元素并不会全部插入Render tree中,像header元素和设置了display:none的元素 就不在渲染树中(但是 设置了visibility :hidden 的元素仍会显示在其中)。


二、reflow(重排 / 回流)

当Render Tree刚构建完时,并不包含元素节点的位置和大小信息。计算这些值的过程称为重排、布局 或 回流。

1、流式布局模型

首先我们要知道,浏览器渲染页面默认采用的是流式布局模型(Flow Based Layout)。

HTML 采用基于流的布局模型,这意味着大多数情况下只要一次遍历就能计算出几何信息。处于流中靠后位置元素通常不会影响靠前位置元素的几何特征,因此布局可以按从左至右、从上至下的顺序遍历文档。但是也有例外情况,比如 HTML 表格的计算就需要不止一次的遍历。

坐标系是相对于根框架而建立的,使用的是上坐标和左坐标。

由于浏览器渲染界面是基于流式布局模型的,所以重排是一个递归的过程。它从根(对应于 HTML 文档的 元素)开始,然后递归遍历部分或所有的框架层次结构,为每一个需要计算的呈现器计算几何信息。

2、重排/布局/回流

所谓重排,实际上是根据Render tree中每个渲染对象的信息计算出各自渲染对象的几何信息(DOM对象的位置和尺寸大小),并将其安置在界面中的正确位置。

由于浏览器渲染界面是基于流式布局模型的,也就是某一个DOM节点信息更改了,就需要对DOM结构进行重新计算,重新布局界面,再次引发重排;只是这个结构更改程度会决定周边DOM更改范围,即全局范围和局部范围。全局范围就是从根节点html开始对整个渲染树进行重新布局,例如当我们改变了窗口尺寸或方向或者是修改了根元素的尺寸或者字体大小等;而局部布局可以是对渲染树的某部分或某一个渲染对象进行重新布局。

在此,总结会引起重排的操作有:

  • 页面首次渲染。
  • 浏览器窗口大小发生改变。
  • 元素尺寸或位置发生改变。
  • 元素内容变化(文字数量或图片大小等等)。
  • 元素字体大小变化。
  • 添加或者删除可见的DOM元素。
  • 激活CSS伪类(例如::hover)。
  • 设置style属性
  • 查询某些属性或调用某些方法
    这里写图片描述

重排也叫回流,实际上,reflow的字面意思也是回流,之所以有的叫做重排,也许是因为更符合中国人的思维。标准文档之所以叫做回流(Reflow),是因为浏览器渲染是基于“流式布局”的模型,流实际就使我们常说的文档流,当dom或者css几何属性发生改变的时候,文档流会受到波动联动的去更改。


三、repaint(重绘)

重绘,就是当页面中元素样式的改变并不影响它在文档流中的位置时,例如更改了字体颜色,浏览器会将新样式赋予给元素并重新绘制的过程称。

常见引起浏览器绘制过程的属性包含:
这里写图片描述


四、减少reflow、优化性能

因为重排一定会引起重绘,而重绘不一定会引起重排,所以我们可以考虑从 减少重排 的角度对网页进行性能优化。

如何减少重排? 比如:

  • 避免设置大量的style属性,因为通过设置style属性改变结点样式的话,每一次设置都会触发一次reflow,所以最好是使用class属性
  • 实现元素的动画,它的position属性,最好是设为absoulte或fixed,这样不会影响其他元素的布局,还可以让动画处于更高的图层(即:z-index的值更大)这也是从图层的角度进行优化的。
  • 动画实现的速度的选择。比如实现一个动画,以1个像素为单位移动这样最平滑,但是reflow就会过于频繁,大量消耗CPU资源,如果以3个像素为单位移动则会好很多。
  • 不要使用table布局,因为table中某个元素旦触发了reflow,那么整个table的元素都会触发reflow。那么在不得已使用table的场合,可以设置table-layout:auto;或者是table-layout:fixed这样可以让table一行一行的渲染,这种做法也是为了限制reflow的影响范围

猜你喜欢

转载自blog.csdn.net/b954960630/article/details/82317999
今日推荐