一、reflow和repaint
重绘是一个元素的外观变化(如:可见性visibility、outline、background-color)但不影响布局所引发的浏览器行为;重绘的代价是高昂的,因为浏览器必须验证DOM树上其他节点元素的可见性。
回流是引起DOM树重新计算的行为;回流更是性能的关键,因为其变化涉及到部分页面(或是整个页面)的布局。一个元素的回流导致了其所有子元素以及DOM中紧随其后的祖先元素的随后的回流。
回流是更加严重的重绘。
导致回流的一些操作:
1、调整窗口大小(Resizing the window)
2、改变字体(Changing the font)
3、增加或者移除样式表(Adding or removing a stylesheet)
4、内容变化,比如用户在input框中输入文字(Content changes, such as a user typing text in
an input box)
5、激活 CSS 伪类,比如 :hover (IE 中为兄弟结点伪类的激活)(Activation of CSS pseudo classes such as :hover (in IE the activation of the pseudo class of a sibling))
6、操作 class 属性(Manipulating the class attribute)
7、脚本操作 DOM(A script manipulating the DOM)
8、计算 offsetWidth 和 offsetHeight 属性(Calculating offsetWidth and offsetHeight)
9、设置 style 属性的值 (Setting a property of the style attribute)
reflow和repaints不可避免,但是可以降低其影响。就好像做手术,没必要动刀子的地方为何要动刀子呢?
1、尽可能在DOM树的最末端改变class
回流可以自上而下,或自下而上的回流的信息传递给周围的节点。回流是不可避免的,但可以减少其影响。尽可能在DOM树的里面改变class,可以限制了回流的范围,使其影响尽可能少的节点。例如,你应该避免通过改变对包装元素类去影响子节点的显示。面向对象的CSS始终尝试获得它们影响的类对象(DOM节点或节点),但在这种情况下,它已尽可能的减少了回流的影响,增加性能优势。
2、避免设置多层内联样式
我们都知道与DOM交互很慢。我们尝试在一种无形的DOM树片段组进行更改,然后整个改变应用到DOM上时仅导致了一个回流。同样,通过style属性设置样式导致回流。避免设置多级内联样式,因为每个都会造成回流,样式应该合并在一个外部类,这样当该元素的class属性可被操控时仅会产生一个reflow。
3、动画效果应用到position属性为absolute或fixed的元素上
动画效果应用到position属性为absolute或fixed的元素上,它们不影响其他元素的布局,所它他们只会导致重新绘制,而不是一个完整回流。这样消耗会更低。
4、牺牲平滑度换取速度
Opera还建议我们牺牲平滑度换取速度,其意思是指您可能想每次1像素移动一个动画,但是如果此动画及随后的回流使用了100%的CPU,动画就会看上去是跳动的,因为浏览器正在与更新回流做斗争。动画元素每次移动3像素可能在非常快的机器上看起来平滑度低了,但它不会导致CPU在较慢的机器和移动设备中抖动。
5、避免使用table布局
避免使用table布局。可能您需要其它些避免使用table的理由,在布局完全建立之前,table经常需要多个关口,因为table是个和罕见的可以影响在它们之前已经进入的DOM元素的显示的元素。想象一下,因为表格最后一个单元格的内容过宽而导致纵列大小完全改变。这就是为什么所有的浏览器都逐步地不支持table表格的渲染(感谢Bill Scott提供)。然而有另外一个原因为什么表格布局时很糟糕的主意,根据Mozilla,即使一些小的变化将导致表格(table)中的所有其他节点回流。