CSS Repaint and Reflow 及其优化

CSS Repaint and Reflow 基本认识及其优化

1. 什么是Repaint/Reflow?

这里写图片描述

浏览器解析的大概工作流程如图所示,可以归纳为四个步骤:

1、解析HTML以构建DOM树:渲染引擎开始解析HTML文档,转换树中的html标签或js生成的标签到DOM节点,它被称为 – 内容树。
2、构建渲染树:解析CSS(包括外部CSS文件和样式元素以及js生成的样式),根据CSS选择器计算出节点的样式,创建另一个树 —- 渲染树。
3、布局渲染树: 从根节点递归调用,计算每一个元素的大小、位置等,给每个节点所应该出现在屏幕上的精确坐标。
4、绘制渲染树: 遍历渲染树,每个节点将使用UI后端层来绘制。

Repain 和 Reflow 分别出现在了第三和第四步。因此我们给出下面的定义:

对于DOM结构中的各个元素都有自己的盒子(模型),这些都需要浏览器根据各种样式(浏览器的、开发人员定义的等)来计算并根据计算结果将元素放到它该出现的位置,这个过程称之为reflow。reflow是整个页面进行重排。

当各种盒子的位置、大小以及其他属性,例如颜色、字体大小等都确定下来后,浏览器于是便把这些元素都按照各自的特性绘制了一遍,于是页面的内容出现了,这个过程称之为repaint。reflow是整个页面进行重排。

可见这两个东东对浏览器渲染页面是很重要的啊,都是会影响性能的,因此我们需要了解一些常见的会引起repaint和reflow的一些操作,并且应该尽量减少以提高渲染速度。

2.引起Repain和Reflow的一些操作

Reflow 的成本比 Repaint 的成本高得多的多。DOM Tree 里的每个结点都会有 reflow 方法,一个结点的 reflow 很有可能导致子结点,甚至父点以及同级结点的 reflow。在一些高性能的电脑上也许还没什么,但是如果 reflow 发生在手机上,那么这个过程是非常痛苦和耗电的。

3.Repain和Reflow的触发场景

  • 触发repaint

    修改 CSS 样式的时候, 例如:1) color的修改,如color=#ddd;2)text-align的修改,如text-align=center;3)a:hover 4):hover引起的颜色等不导致页面回流的style变动。 等等

  • 触发reflow

    1. 增加、删除、修改、移动DOM 结点时,会导致 Reflow 或 Repaint。
    2. 动画。:hover等伪类引起的元素表现改动,display=none等造成页面回流;
    3. 修改网页的默认字体时、font类style的修改;
    4. width/height/border/margin/padding的修改,如width=778px;
    5. background的修改,注意着字面上可能以为是重绘,但是浏览器确实回流了,经过浏览器厂家的优化,部分background的修改只触发repaint,当然IE不用考虑;
    6. scroll页面时,这个不可避免;
    7. resize窗口时,对浏览器大小的缩放,移动端的话,还没玩过能拖动程序,resize程序窗口大小的多窗口操作系统。
    8. 读取元素的属性(这个无法理解,但是技术达人是这么说的,那就把它当做定理吧):读取元素的某些属性(offsetLeft、offsetTop、offsetHeight、offsetWidth、scrollTop/Left/Width/Height、clientTop/Left/Width/Height、getComputedStyle()、currentStyle(in IE));
  • **注:**display:none 会触发 reflow,而 visibility:hidden 只会触发 repaint,因为没有发现位置变化。

4.如何优化?

Reflow是不可避免的,只能将Reflow对性能的影响减到最小,给出下面几条建议:

下面是大神Nicole Sullivan的原话:

  1. Change classes on the element you wish to style (as low in the dom tree as possible) 尽可能在DOM末梢通过改变class来修改元素的style属性
  2. Avoid setting multiple inline styles 避免设置多项内联样式
  3. Apply animations to elements that are position fixed or absolute 设置动画元素position属性为fixed或者absolute
  4. Trade smoothness for speed 牺牲平滑度满足性能
  5. Avoid tables for layout 避免使用table进行布局
  6. Avoid JavaScript expressions in the CSS (IE only) 避免在CSS中使用运算式

1.不要一条一条地修改 DOM 的样式。与其这样,还不如预先定义好 css 的 class,然后修改 DOM 的 className:

// 不好的写法
var left = 10,
top = 10;
el.style.left = left + "px";
el.style.top  = top  + "px";
// 推荐写法
el.className += " theclassname";

2.把 DOM 离线后修改。如:
a) 使用 documentFragment 对象在内存里操作 DOM。
b) 先把 DOM 给 display:none (有一次 repaint),然后你想怎么改就怎么改。比如修改 100 次,然后再把他显示出来。
c) clone 一个 DOM 节点到内存里,然后想怎么改就怎么改,改完后,和在线的那个的交换一下。

3.不要把 DOM 节点的属性值放在一个循环里当成循环里的变量。不然这会导致大量地读写这个结点的属性。

4.尽可能的修改层级比较低的 DOM节点。当然,改变层级比较底的 DOM节点有可能会造成大面积的 reflow,但是也可能影响范围很小。

5.为动画的 HTML 元件使用 fixed 或 absoult 的 position,那么修改他们的 CSS 是会大大减小 reflow 。

6.千万不要使用 table 布局。因为可能很小的一个小改动会造成整个 table 的重新布局。
7. 避免在CSS中使用运算式。一旦存在动画性的repaint/reflow,那么每一帧动画都会进行计算,性能消耗不容小觑。


参考文章
Repaint 、Reflow 的基本认识和优化 (2)
探讨css中repaint和reflow
影响reflow的因素及其优化

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值