【前端指南】浏览器渲染页面的原理及流程

浏览器渲染页面的原理及流程

  1. 根据HTML文件构建DOM树和CSSOM树,构建树的期间如果遇见JS,则阻塞DOM树和CSSOM树的构建,优先加载JS文件,加载完毕再继续构建DOM树及CSSOM树
  2. 构建渲染树render tree
  3. 页面重绘repaint与重排reflow,页面渲染完成后,若JS操作了DOM节点,根据JS对DOM操作动作的大小,浏览器对页面进行重绘或重排

构建DOM树及CSSOM树

构建DOM树
  • HTML 文档中的所有内容皆是节点,各节点之间拥有层级关系,如父子关系、兄弟关系等,彼此相连,构成DOM树。最常见的几种节点有:文档节点、元素节点、文本节点、属性节点、注释节点,DOM节点树中节点与HTML文档中内容一一对应
  • DOM树构建过程:读取html文档,将字节转换成字符,确定tokens(标签),再将tokens转换成节点,以节点构建 DOM 树
  • 在这里插入图片描述
构建CSSOM树
  • CSS文档中,所有元素皆是节点,与HTML文件中的标签节点一一对应。CSS中各节点之间同样拥有层级关系,如父子关系、兄弟关系等,彼此相连,构成CSSOM树

  • 在构建DOM树的过程中,在 HTML 文档的 head 标签中遇到 link 标签,该标签引用了一个外部CSS样式表。由于预见到需要利用该CSS资源来渲染页面,浏览器会立即发出对该CSS资源的请求,并进行CSSDOM树的构建

  • CSSOM树构建过程与DOM树构建流程一致:读取CSS文档,将字节转换成字符,确定tokens(标签),再将tokens转换成节点,以节点构建 CSSOM 树

  • 在这里插入图片描述

  • 在这里插入图片描述

  • .CSS文件,又名层叠样式表。当CSSOM树生成节点时,每一个节点首先会继承其父节点的所有样式,层叠覆盖,然后再以"向下级联"的规则,为该节点应用更具体的样式,递归生成CSSOM树

    • 譬如,上右图中第二层的p节点,有父节点body,因此该p将继承body节点的样式:“font-size: 16px;”。然后再应用该p节点自身的样式:“font-weight: bold;”。所以最终该p节点的样式为:“font-size: 16px;font-weight: bold;”。
加载JS
  • 若在构建DOM树的过程中,当 HTML 解析器遇到一个 script 标记时,即遇到了js,将立即阻塞DOM树的构建,将控制权移交给 JavaScript 引擎,等到 JavaScript 引擎运行完毕,浏览器才会从中断的地方恢复DOM树的构建
  • 其根本原因在于,JS会对DOM节点进行操作,浏览器无法预测未来的DOM节点的具体内容,为了防止无效操作,节省资源,只能阻塞DOM树的构建
  • 譬如,若不阻塞DOM树的构建,若JS删除了某个DOM节点A,那么浏览器为构建此节点A花费的资源就是无效的
  • 若在HTML头部加载JS文件,由于JS阻塞,会推迟页面的首绘。为了加快页面渲染,一般将JS文件放到HTML底部进行加载,或是对JS文件执行async或defer加载

构建渲染树

  • 渲染树(Render Tree)由DOM树、CSSOM树合并而成,但并不是必须等DOM树及CSSOM树加载完成后才开始合并构建渲染树。三者的构建并无先后条件,亦非完全独立,而是会有交叉,并行构建。因此会形成一边加载,一边解析,一边渲染的工作现象
  • 构建渲染树,根据渲染树计算每个可见元素的布局,并输出到绘制流程,将像素渲染到屏幕上

页面的重绘(repaint)与重排(reflow)

重绘(repaint)
  • 屏幕的一部分要重绘。渲染树节点发生改变,但不影响该节点在页面当中的空间位置及大小。譬如某个div标签节点的背景颜色、字体颜色等等发生改变,但是该div标签节点的宽、高、内外边距并不发生变化,此时触发浏览器重绘(repaint)
重排(reflow)
  • 也有称回流
  • 当渲染树节点发生改变,影响了节点的几何属性(如宽、高、内边距、外边距、或是float、position、display:none;等等),导致节点位置发生变化,此时触发浏览器重排(reflow),需要重新生成渲染树。譬如JS为某个p标签节点添加新的样式:“display:none;”。导致该p标签被隐藏起来,该p标签之后的所有节点位置都会发生改变。此时浏览器需要重新生成渲染树,重新布局,即重排(reflow)

注意:重排必将引起重绘,而重绘不一定会引起重排

何时回引起重排?
  • 当页面布局和几何属性改变时就需要重排。下述情况会发生浏览器重排:
    1. 添加或者删除可见的DOM元素
    2. 元素位置改变——display、float、position、overflow等等
    3. 元素尺寸改变——边距、填充、边框、宽度和高度
    4. 内容改变——比如文本改变或者图片大小改变而引起的计算值宽度和高度改变
    5. 页面渲染初始化
    6. 浏览器窗口尺寸改变——resize事件发生时;
如何减少和避免重排
  • Reflow 的成本比 Repaint 的成本高得多的多。一个节点的 Reflow 很有可能导致子节点,甚至父节点以及兄弟节点的 Reflow 。在一些高性能的电脑上也许还没什么,但是如果 Reflow 发生在手机上,那么这个过程是延慢加载和耗电的
    1. 直接改变className,如果动态改变样式,则使用cssText(考虑没有优化的浏览器)
      • className可以用来改变标签元素的css类选择器,从而改变元素的样式
      • cssText本质是设置HTML元素的style属性值
    2. 让要操作的元素进行”离线处理”,处理完后一起更新
      • 使用DocumentFragment进行缓存操作,引发一次回流和重绘
        • 不是真实DOM树的一部分,他的变化不会引起DOM树的重新渲染的操作,且不会导致性能等问题
      • 使用display:none技术,只引发两次回流和重绘
        • 将元素设为无,即页面中不占任何位置
        • 效果看起来像是"去除"
      • 使用cloneNode(true or false) 和 replaceChild 技术,引发一次回流和重绘
        1. deep-创建节点拷贝并返回该副本,克隆所有属性和值,TRUE or FALSE-克隆所有后代
        2. 永新节点替换某个子节点,新节点可以是文档中已经存在的节点也可以是创建的新的节点
          • node.replaceChild(newNode, oldNode)
          • newNode,希望插入的节点对象
          • oldNode,希望删除的节点对象
    3. 不要经常访问会引起浏览器flush队列的属性,如果你确实要访问,利用缓存
    4. 让元素脱离动画流,减少回流的Render Tree的规模
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值