JS回流与重绘及优化策略

1、浏览器渲染过程

从上面这个图上可以看出,浏览器渲染过程如下:

  • 解析HTML,生成DOM树,解析CSS,生成样式规则
  • 将DOM树和样式规则结合,生成渲染树(Render Tree)
  • Layout(回流):根据生成的渲染树,进行回流(Layout),得到节点的几何信息(位置,大小)
  • Painting(重绘):根据渲染树以及回流得到的几何信息,得到节点的绝对像素
  • Display:将各层信息发送给GPU,GPU进行合并,最后展示在页面上

为了构建渲染树,浏览器主要完成了以下工作:

从DOM树的根节点开始遍历每个可见节点。 对于每个可见的节点,找到CSSOM树中对应的规则,并应用它们。根据每个可见节点以及其对应的样式,组合生成渲染树。

2、回流与重绘

1.关于回流与重绘

  • 回流(Reflow)

当Render Tree中部分或全部元素的尺寸,结构或者某些属性发生改变时,浏览器重新渲染部分或全部文档的过程

  • 重绘(Repaint)

而重绘则是视觉效果变化引起的重新绘制。比如 color 或者 background 发生了变化,那就该给触发重绘的元素化化妆,化成它想要的样子

回流必将引起重绘,而重绘不一定会引起回流

2.导致回流发生的一些因素:

  • 浏览器窗口大小发生改变
  • 元素字体大小变化
  • 增加或者移除样式表
  • 内容变化,比如用户在 input 框中输入文字, CSS3 动画,文字数量或者图片大小改变等
  • 激活 CSS 伪类,比如 :hover
  • 操作class属性
  • 添加或删除可见的DOM元素
  • 计算offsetWidth和offsetHeight属性
  • 设置 style 属性的值
  • 页面首次渲染
  • 元素尺寸或者位置发生改变

3.一些常用且会导致回流的属性和方法

clientWidth,clientHeight,clientTop,clientLeft

offsetWidth,offsetHeight,offsetTop,offsetLeft 

scrollWidth,scrollHeight,scrollTop,scrollLeft,scrollIntoView()

4.性能影响

现代浏览器会对频繁的回流或重绘操作进行优化: 浏览器会维护一个队列,把所有引起回流和重绘的操作放入到队列中,如果队列中的任务数量或者时间间隔达到一个阈值,浏览器会将队列清空,进行一次批处理,这样可以把多次回流和重绘变成一次

5.如何避免回流和重绘

CSS:

  • 避免使用table布局
  • 尽可能在DOM树的最末端改变class
  • 避免设置多层内联样式
  • 将动画效果应用到position属性为absolute或fixed的元素上
  • 避免使用CSS表达式
  • 用transform 代替 top,left ,margin-top, margin-left... 这些位移属性

JS:

  • 避免频繁操作样式,最好一次性重写style属性,或者将样式列表定义为class并一次性更改class属性
  • 避免频繁操作DOM,创建一个documentFragment,在它上面应用所有DOM操作,最后再把它添加到文档中
  • 也可以先为元素设置display: none,操作结束后再把它显示出来。因为在display属性为none的元素上进行的DOM操作不会引发回流和重绘
  • 避免频繁读取会引发回流/重绘的属性,如果确实需要多次使用,就用一个变量缓存起来
  • 对具有复杂动画的元素使用绝对定位,使它脱离文档流,否则会引起父元素及后续元素频繁回流
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值