码迷,mamicode.com
首页 > Web开发 > 详细

css reflow和repaint

时间:2016-05-23 13:09:34      阅读:190      评论:0      收藏:0      [点我收藏+]

标签:

浏览器为了重新渲染部分或整个页面,重新计算页面元素位置和几何结构(geometries)的进程叫做 reflow。由于 reflow 是一种浏览器中的用户拦截(user-blocking)操作,所以了解如何减少 reflow 次数,及不同的文档属性(DOM 层级(DOM depth),CSS 效率,不用类型的 style 变化)对 reflow 次数的影响对开发者来说非常必要。有时 reflow 页面中的一个元素会 reflow 它的父元素(译注:这里是复数)以及所有子元素。

Yahoo!性能工程师Nicole Sullivan写了一篇非常值得一读的分析Reflow和Repaint的文章,原文地址:http://www.stubbornella.org/content/2009/03/27/reflows-repaints-css-performance-making-your-javascript-slow/以下是克军的译本:

repaint(重绘)是在一个元素的外观被改变,但没有改变布局的情况下发生,如改变visibility、outline、前景色。 "According to Opera, repaint is expensive because the browser must verify the visibility of all other nodes in the DOM tree."

当repaint发生时,浏览器会验证DOM树上的所有其它结点的visibility属性。 

reflow(回流)是导致DOM脚本执行低效的关键因素之一。页面上任何一个结点触发reflow,都会导致它的子结点及祖先结点重新渲染。Nicole举了个例子:
 
 技术分享
 
当p结点上发生reflow,div.error和body也会重新渲染,甚至h5和ol也会受到影响。

 Nicole总结了在哪些情况下会导致reflow发生:
  • 改变窗囗大小
  • 改变文字大小
  • 添加/删除样式表
  • 内容的改变,如用户在输入框中敲字(这样也会-_-||)
  • 激活伪类,如:hover (IE里是一个兄弟结点的伪类被激活)
  • 操作class属性
  • 脚本操作DOM
  • 计算offsetWidth和offsetHeight
  • 设置style属性 
reflow是不可避免的,只能将reflow对性能的影响减到最小。Nicole提出6点建议:

1.   Change classes on the element you wish to style (as low in the dom tree as possible)
尽可能限制reflow的影响范围。以上面的代码为例,要改变p的样式,class不要加在div上,通过父级元素影响子元素不好。最好直接加在p上。

2   Avoid setting multiple inline styles 
通过设置style属性改变结点样式的话,每设置一次都会导致一次reflow。所以最好通过设置class的方式。

3  Apply animations to elements that are position fixed or absolute 
实现元素的动画,它的position属性应当设为fixed或absolute,这样不会影响其它元素的布局。

4  Trade smoothness for speed 
权衡速度的平滑。比如实现一个动画,以1个像素为单位移动这样最平滑,但reflow就会过于频繁,CPU很快就会被完全占用。如果以3个像素为单位移动就会好很多。

5   Avoid tables for layout 
不要用tables布局的另一个原因就是tables中某个元素一旦触发reflow就会导致table里所有的其它元素reflow。在适合用table的场合,可以设置table-layout为auto或fixed,这样可以让table一行一行的渲染,这种做法也是为了限制reflow的影响范围。

6   Avoid JavaScript expressions in the CSS (IE only)
很多情况下都会触发reflow,如果css里有expression,每次都会重新计算一遍。

 

有多种用户操作和 DHTML 变化可能会触发 reflow。调整浏览器窗口的大小,用 javascript 计算样式(computed styles),在 DOM 中创建删除元素,改变元素的 class 都会触发 reflow。值得注意的是,有些操作会多次触发 reflow,超出你的想象。下图源自 Steve Souders 的演讲 "Even Faster Web Sites":

技术分享

从上表可以很明显的看出,在所有浏览器中并非所有 javascript 控制的样式都触发 reflow,即使触发了触发的次数也不尽相同。同时可以看出现代浏览器在控制 reflow 次数方面做的越来越好。

在 Google,我们通过多种方式对我们的页面及 Web 应用测速,同时 reflow 是我们增加 UI 时考虑的一个关键因素。我们致力于传达轻快的(lively),交互性强的(interactive)和令人愉悦的(delightful)的用户体验。

原则

下面是一些减小 reflow 的原则:

    1. 减少不必要的 DOM 层级(DOM depth)。改变 DOM 树中的一级会导致所有层级的改变,上至根部,下至被改变节点的子节点。这导致大量时间耗费在执行 reflow 上面。
    2. 尽量减少 CSS 规则,去除未用到的 CSS。
    3. 如果做复杂的表现变化,如动画,让它脱离文档流。用绝对定位或 fixed 定位来完成。
    4. 避免不必要的复杂的 CSS 选择器,尤其是后代选择器(descendant selectors),因为为了匹配选择器将耗费更多的 CPU。

css reflow和repaint

标签:

原文地址:http://www.cnblogs.com/itcoco/p/5519444.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!