目录
  1. 1. 浏览器渲染网页的两个线程
    1. 1.1. 页面在文档加载完成之后到完全显示中间的过程:
  2. 2. 重绘与回流
    1. 2.1. 回流reflow
      1. 2.1.1. 如何避免回流
        1. 2.1.1.1. 其他:
        2. 2.1.1.2.
    2. 2.2. 重绘repaint
      1. 2.2.1. 触发重绘的有这些:
  3. 3. 优化重绘与回流 注意1和2就行
    1. 3.1. PS
    2. 3.2.
重绘与回流

浏览器渲染网页的两个线程

一条渲染js,一条渲染UI(css)
两者是互斥的

页面在文档加载完成之后到完全显示中间的过程:

  1. 根据文档生成DOM树(包括display:none的节点)

  2. 在DOM树基础上根据节点的几何属性(margin/padding/width/height等)生成render树(不包括display:none、head节点但会包含visibility:hidden节点)

  3. 在render树基础上进行一步渲染包括color,outline等样式

重绘与回流

回流reflow

当render树中的一部分或者全部因为大小边距元素因改变了自身的宽高、布局、显示或隐藏,或者元素内部的文字结构发生变化,导致需要重新构建页面的时候,这个过程叫做回流。

width    宽度                               	  top                                   	text-align  文本对齐方式  
    height 高度 bottom font-weight 字体宽度
    padding 内边距 left line-height 行高
    margin 外边距 right vertival-align 垂直方向对齐方式
    display 显示框类型 position font-size 字体大小
border 外边框线 float white-space 设置如何处理元素内的空白。
    over-flow-y 垂直方向溢出隐藏

如何避免回流

  1. 一是不使用以上能触发图层回流的属性
  2. 二是建立一个图层,让回流在这些图层里面进行,限制回流和重绘的范围,减少浏览器的运算工作量

其他:

css图层

css 中有一个重要的概念—— “划分图层”。
在页面加载完dom之后,浏览器会根据自身制定的一些特殊css 属性对页面进行划分为一个个图层。
例如:
有 position: absolute 属性的元素会被浏览器集中归纳到一个图层中,
有 position: fixed 的元素也会被浏览器集中归纳到另外一个图层中
还有一些例如:transform: translateZ(0)…. 也会被浏览器集中归纳到另外一个图层中

图层内部做了什么:

1、对图层里面的节点做回流和重布局运算,计算出他们的样式

2、生成图形和位置

3、将每个节点绘制填充在图层位图中

4、将涂层作为纹理发送到GPU上

5、将所有的图层合并,显示在浏览器的页面上

总结:滥用图层会让页面进行了太多的合并运算而导致页面卡顿。所以图层的用途应该让那些经常要进行位置结构,布局变换的元素去使用。例如轮播图。

重绘repaint

当元素的一部分属性发生变化,如外观背景色不会引起布局变化而需要重新渲染的过程叫做重绘.
当一个元素自身的宽高,布局,及显示或隐藏没有改变,而只改变了元素的外观风格的时候,就会产生重绘。

回流必定触发重绘,而重绘不一定触发回流

触发重绘的有这些:

color 字体颜色
border-style 外边框线颜色
border-radius 圆角
visibility 规定元素是否可见
text-decoration 文本修饰符
background 背景属性
background-image 背景图像
background-position 背景图定位
background-repeat 背景图去重复
background-size 背景图大小
outline-color 设置点状轮廓的颜色
outline 设置 4 个边框的样式:
outline-style 设置轮廓的样式:
outline-width 设置元素整个轮廓的宽度
box-shadow 设置盒子阴影

优化重绘与回流 注意1和2就行

  1. 用transform 代替 top,left ,margin-top, margin-left… 这些位移属性
  2. 用opacity 代替 visibility,但是要同时有translate3d 或 translateZ 这些可以创建的图层的属性存在才可以阻止回流,如果不加 transform: translateZ(0) 配合opacity的话还是会产生回流的,而只用visibility 就只会产生重绘不会产生回流,而 opacity 加上 transform: translateZ/3d 这个属性之后便不会发生回流和重绘了
  3. 不要使用 js 代码对dom 元素设置多条样式,选择用一个 className 代替之。
  4. 如果确实需要用 js 对 dom 设置多条样式那么可以将这个dom 先隐藏,然后再对其设置
  5. 不要在循环内获取dom 的样式例如:offsetWidth, offsetHeight, clientWidth, clientHeight… 这些。浏览器有一个回流的缓冲机制,即多个回流会保存在一个栈里面,当这个栈满了浏览器便会一次性触发所有样式的更改且刷新这个栈。但是如果你多次获取这些元素的实际样式,浏览器为了给你一个准确的答案便会不停刷新这个缓冲栈,导致页面回流增加。
  6. 所以为了避免这个问题,应该用一个变量保存在循环体外。
  7. 不要使用table 布局,因为table 的每一个行甚至每一个单元格的样式更新都会导致整个table 重新布局
  8. 动画的速度按照业务按需决定
  9. 对于频繁变化的元素应该为其加一个 transform 属性,对于视频使用video 标签
  10. 必要时可以开启 GPU 加速,但是不能滥用

PS

display:none,会脱离文档流,不占据页面空间;

visibility:hidden,只是隐藏内容,并没有脱离文档流,会占据页面的空间。
display:none会引起回流和重绘,visibility:hidden会引起重绘

参考 :
1.display和visibility的区别以及回流和重绘
2.前端:性能优化之回流和重绘

文章作者: ruqiuvy
文章链接: https://github.com/yiyeruqiuvy/2022/11/07/%E9%87%8D%E7%BB%98%E4%B8%8E%E5%9B%9E%E6%B5%81/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 一夜入秋非生之所
打赏
  • 微信
  • 支付寶

评论