跳至主要內容

浏览器渲染

星星大约 4 分钟

浏览器渲染

回流(重排)

  • 当渲染树中部分或者全部元素的尺寸、结构或者属性发生变化时,浏览器会重新渲染部分或者全部文档的过程就称为回流
  • 会导致回流的操作
    • 页面的首次渲染
    • 浏览器的窗口大小发生变化
    • 元素的内容发生变化
    • 元素的尺寸或者位置发生变化
    • 元素的字体大小发生变化
    • 激活 CSS 伪类
    • 查询某些属性或者调用某些方法
    • 添加或者删除可见的 DOM 元素
  • 在触发回流(重排)的时候,由于浏览器渲染页面是基于流式布局的,所以当触发回流时,会导致周围的 DOM 元素重新排列,它的影响范围有两种:
    • 全局范围:从根节点开始,对整个渲染树进行重新布局
    • 局部范围:对渲染树的某部分或者一个渲染对象进行重新布局

重绘

  • 当页面中某些元素的样式发生变化,但是不会影响其在文档流中的位置时,浏览器就会对元素进行重新绘制,这个过程就是重绘。

  • 会导致重绘的操作

    • color、background 相关属性:background-color、background-image 等
    • outline 相关属性:outline-color、outline-width 、text-decoration
    • border-radius、visibility、box-shadow
  • 当触发回流时,一定会触发重绘,但是重绘不一定会引发回流。

减少回流重绘

  • 操作 DOM 时,尽量在低层级的 DOM 节点进行操作
  • 不要使用 table 布局, 一个小的改动可能会使整个 table 进行重新布局
  • 使用 CSS 的表达式
  • 不要频繁操作元素的样式,对于静态页面,可以修改类名,而不是样式。
  • 使用 absolute 或者 fixed,使元素脱离文档流,这样他们发生变化就不会影响其他元素
  • 避免频繁操作 DOM,可以创建一个文档片段 documentFragment,在它上面应用所有 DOM 操作,最后再把它添加到文档中
  • 将元素先设置 display: none,操作结束后再把它显示出来。因为在 display 属性为 none 的元素上进行的 DOM 操作不会引发回流和重绘。
  • 将 DOM 的多个读操作(或者写操作)放在一起,而不是读写操作穿插着写。这得益于浏览器的渲染队列机制。

浏览器的渲染队列

  • 浏览器针对页面的回流与重绘,进行了自身的优化——渲染队列

  • 浏览器会将所有的回流、重绘的操作放在一个队列中,当队列中的操作到了一定的数量或者到了一定的时间间隔,浏览器就会对队列进行批处理。这样就会让多次的回流、重绘变成一次回流重绘。

  • 当我们把一个 DocumentFragment 节点插入文档树时,插入的不是 DocumentFragment 自身,而是它的所有子孙节点。在频繁的 DOM 操作时,我们就可以将 DOM 元素插入 DocumentFragment,之后一次性的将所有的子孙节点插入文档中。DocumentFragment 不是真实 DOM 树的一部分,它的变化不会触发 DOM 树的重新渲染,这样就大大提高了页面的性能。

BFC

bfc 的效果

让处于 BFC 内部的元素与外部的元素相互隔离,使内外元素的定位不会相互影响

  • 1.BFC 内部的盒子会在垂直方向上一个接一个排列(bfc 里面也有正常的文档流)
  • 2.解决外边距重叠
  • 3.BFC 容器在计算高度的时候,会连浮动元素计算在内

创建 bfc

  • 浮动 float:left / right 可以将容器变为 BFC
  • 定位 position: absolute / fixed 可以将容器变为 BFC
  • 行内块 display: inline-block
  • 表格单元 diaplay:table-cell,只要元素为 table- ... 的形式都可以
  • overflow:auto / hidden / overlay / scroll
  • 弹性盒子 (display:flex/inline-flex)

BFC 容器 的范围

一个 BFC 包含该上下文的子元素,但不包含创建了新 BFC 的子元素的内部元素, 即:A>B>C>D ,当 A 为 BFC 容器,A 能包含 B C D ,但是当 C 为 BFC 容器时 A 就不能作用到 D 容器,那么就是说一个元素不能同时存在在两个 BFC 里面

上次编辑于:
贡献者: wanghongjie