reflow和repaint(摘录自张鑫旭的翻译)
//正文开始
关于回流(reflows)与重绘(repaints),我已经在twitter和delicious上发布,但是并没有在演讲中提到或是以文章形式发布。
第一次让我开始思考关于回流(reflows)与重绘(repaints)的问题是在和ParisWeb上的Mr. Glazman做一个firey交换的时候。我可能有一些顽固,但是我确实听了他的一些理论。
Stoyan和我开始讨论如何量化这个问题。
展望性能社区,除了一些典型的黑盒实验外,需要与浏览器厂商有更多的合作。对于性能,浏览器制造者知道哪些是重要的,哪些是不相干的。Opera列出“reflow和repaint是减缓JavaScript的三大主要原因之一”一文,所以其肯定值得一看。// zxx: Firefox浏览器相关内容可以看这里;Safari可以看这里。
让我们从一些背景资料开始,当一个元素的外观的可见性visibility发生改变的时候,重绘(repaint)也随之发生,但是不影响布局。类似的例子包括:outline, visibility, or background color。根据Opera浏览器,重绘的代价是高昂的,因为浏览器必须验证DOM树上其他节点元素的可见性。而回流更是性能的关键因为其变化涉及到部分页面(或是整个页面)的布局。一个元素的回流导致了其所有子元素以及DOM中紧随其后的祖先元素的随后的回流。
例如:
<body>
<div class="error">
<h4>我的组件</h4>
<p><strong>错误:</strong>错误的描述…</p>
<h5>错误纠正</h5>
<ol>
<li>第一步</li>
<li>第二步</li>
</ol>
</div>
</body>
在上面的HTML片段中,对该段落(<p>标签)回流将会引发强烈的回流,因为它是一个子节点。这也导致了祖先的回流(div.error和body – 视浏览器而定)。此外,h5和ol也会有简单的回流,因为其在DOM中在回流元素之后。就Opera而言,大部分的回流将导致页面的重新渲染。
Opera原文:Reflows are very expensive in terms of performance, and is one of the main causes of slow DOM scripts, especially on devices with low processing power, such as phones. In many cases, they are equivalent to laying out the entire page again.
既然它们对性能影响如此可怕,那什么会导致回流呢?
不幸的是,很多的东西,其中一些还与CSS的书写特别相关。
- 调整窗口大小(Resizing the window)
- 改变字体(Changing the font)
- 增加或者移除样式表(Adding or removing a stylesheet)
- 内容变化,比如用户在input框中输入文字(Content changes, such as a user typing text in
an input box) - 激活 CSS 伪类,比如 :hover (IE 中为兄弟结点伪类的激活)(Activation of CSS pseudo classes such as :hover (in IE the activation of the pseudo class of a sibling))
- 操作 class 属性(Manipulating the class attribute)
- 脚本操作 DOM(A script manipulating the DOM)
- 计算 offsetWidth 和 offsetHeight 属性(Calculating offsetWidth and offsetHeight) 根据此可以实现一个jquery插件,让元素回流并重绘。ex. el.style.left=20px; a = el.offsetHeight;el.style.left=22px;
- 设置 style 属性的值 (Setting a property of the style attribute)
Mozilla关于回流的文章罗列了导致回流的要点以及何时可以减少他们。
如何避免回流或将它们对性能的影响降到最低?
注意:这里我限定了自己只能讨论CSS对回流的影响,如果您是一位JavaScript程序员,我是推荐您读一下我的reflow链接(zxx: 原作者收藏标记的一些关于reflow的一些文章或页面链接),有一些非常好的东西,没有直接关系到CSS。
- 如果想设定元素的样式,通过改变元素的 class 名 (尽可能在 DOM 树的最末端)(Change classes on the element you wish to style (as low in the dom tree as possible))
- 避免设置多项内联样式(Avoid setting multiple inline styles)
- 应用元素的动画,使用 position 属性的 fixed 值或 absolute 值(Apply animations to elements that are position fixed or absolute)
- 权衡平滑和速度(Trade smoothness for speed)
- 避免使用table布局(Avoid tables for layout)
- 避免使用CSS的JavaScript表达式 (仅 IE 浏览器)(Avoid JavaScript expressions in the CSS (IE only))
尽可能在DOM树的最末端改变class
避免设置多层内联样式
动画效果应用到position属性为absolute或fixed的元素上
牺牲平滑度换取速度
避免使用table布局
Jenny Donnelly, YUI 数据表格 widget的所有者,建议使用数据表格的固定布局以便更有效的布局算法,任何表格-布局的值除了”auto”将引发一个固定布局,根据CSS2.1规范,这将允许表格一行一行的呈递。Quirksmode显示,大部分的浏览器对表格布局属性支持良好。
In this manner, the user agent can begin to lay out the table once the entire first row has been received. Cells in subsequent rows do not affect column widths. Any cell that has content that overflows uses the ‘overflow’ property to determine whether to clip the overflow content.
This algorithm may be inefficient since it requires the user agent to have access to all the content in the table before determining the final layout and may demand more than one pass.
避免使用CSS的JavaScript表达式
回流(reflow)这个名词指的是网络浏览器为了重新渲染部分或全部的文档而重新计算文档中元素的位置和几何结构的过程。因为回流(reflow)在浏览器中属于一种用户主导的模块化操作,所以知道如何去改进回流(reflow)时间以及知道各种文档属性(DOM节点深度,css的渲染效率,各种各样的样式改变)对回流(reflow)时间的影响对于开发人员讲是很有帮助的。有时候,即使仅仅回流一个单一的元素,也可能要求它的父元素以及任何跟随它的元素也产生回流。
有大量的用户行为以及潜在的DHTML改变会触发回流(reflow)。例如,改变浏览器窗口的大小,使用一些JavaScript方法,包括计算样式,对DOM进行元素的添加或删除,或是改变元素的class等。值得注意的是有一些操作产生的回流(reflow)时间可能要比你原先预想的要多——您可以参考下面这张史蒂芬•桑德斯(Steve Souders)的“更快的网站(Even Faster Web Sites)”一文中提到的图表。

从上边的表格我们可以清晰的看到并不是所有JavaScript改变的样式都会在浏览器中产生回流(reflow),所花费的回流(reflow)时间也是多样的。而且我们或多或少可以看到,现代浏览器在回流(reflow)时间上要做的更好一些。
借助Google,我们用各种方式测试了我们页面以及应用程序的速度,发现在界面上添加功能时回流是个至关重要必须考虑的因素,我们应尽最大努力传达生动的,交互的,愉悦的用户体验。
指导
以下是一些简单的指导方针可以帮助你页面上的回流(reflow)减到最小。
1.减少不必要的DOM深度。因为无论你改变DOM节点树上任何一个层级都会影响节点树的每个层级——从根结点一直到修改的子节点。不必要的节点深度将导致执行回流时花费更多的时间。
2. 精简css,去除没有用处的css
3. 如果你想让复杂的表现发生改变,例如动画效果,那么请在这个流动线之外实现它。使用position-absolute或position-fixed来实现它。
4. 避免不必要的复杂的css选择符,尤其是使用子选择器,或消耗更多的CPU去做选择器匹配。
reflow和repaint(摘录自张鑫旭的翻译)的更多相关文章
- 您可能不知道的CSS元素隐藏“失效”以其妙用——张鑫旭
一.CSS元素隐藏 在CSS中,让元素隐藏(指屏幕范围内肉眼不可见)的方法很多,有的占据空间,有的不占据空间:有的可以响应点击,有的不能响应点击.后宫选秀——一个一个看. { display: non ...
- [css]【转载张鑫旭】我是如何对网站CSS进行架构的
一.写在前面的 都是自己积累形成的一些东西,可能带有明显的个人印记.不是专业内容,不是权威指南,只是展示一点自己的观点,借此希望能与各位优秀的同行交流看法,见解.以得到进步与提高. 二.我所知的一些过 ...
- [转] HTML5终极备忘大全(图片版+文字版)---张鑫旭
by zhangxinxu from http://www.zhangxinxu.com本文地址:http://www.zhangxinxu.com/wordpress/?p=1544 一.前言兼图片 ...
- [转] 小tip: 使用CSS将图片转换成模糊(毛玻璃)效果 ---张鑫旭
by zhangxinxu from http://www.zhangxinxu.com本文地址:http://www.zhangxinxu.com/wordpress/?p=3804 去年盛夏之时, ...
- [转] 小tip: 使用CSS将图片转换成黑白(灰色、置灰) ---张鑫旭
by zhangxinxu from http://www.zhangxinxu.com本文地址:http://www.zhangxinxu.com/wordpress/?p=2547 //zxx: ...
- [转] 翻译-高质量JavaScript代码书写基本要点 ---张鑫旭
by zhangxinxu from http://www.zhangxinxu.com本文地址:http://www.zhangxinxu.com/wordpress/?p=1173 原文作者:St ...
- 图片旋转+剪裁js插件(兼容各浏览器) « 张鑫旭-鑫空间-鑫生活
图片旋转+剪裁js插件(兼容各浏览器) « 张鑫旭-鑫空间-鑫生活 图片旋转+剪裁js插件(兼容各浏览器) by zhangxinxu from http://www.zhangxinxu.com 本 ...
- 好吧,CSS3 3D transform变换,不过如此!——张鑫旭
一.写在前面的秋裤 早在去年的去年,我就大肆介绍了2D transform相关内容.看过海贼王的都知道,带D的家伙都不是好惹的,2D我辈尚可以应付,3D的话,呵呵,估计我等早就在千里之外被其霸气震晕了 ...
- 分享张鑫旭大神的,纯css打字小技巧,我顺便收藏一下
CSS代码: .typing { width: 15em; white-space: nowrap; border-right: 2px solid transparent; animation: t ...
随机推荐
- GIT 版本控制常用命令学习汇总
GIT 版本控制常用命令汇总 git version 查看当前git版本信息 git help 获取全部命令帮助信息 git help <command> 获取指定命令帮助信息 git c ...
- 破除Odoo 菜单栏提示 99+
菜单栏提示利用的menu对象的needaction_counter属性,默认只能显示99个 多于99则显示99+ 如果希望显示完整的数字,则需要改动如下两个地方. 一.menu菜单的显示限制: 将第一 ...
- Swift小练习-引导页
任何一门语言,只要长期不用就会忘掉,得时不时的敲敲小项目,练练手; let scrollViewBG = UIScrollView.init(frame: SLScreenRect) let imag ...
- java面向对象_构造器
构造器(构造方法):是类中定义的方法. 1)常常用于给成员变量赋值: 2)与类同名,没有返回值类型,也不能写void: 3)在创建对象时被自动调用.所以构造方法的访问修饰符要用public,才能被自动 ...
- eclipse 中的注释 快捷键
(1)Ctrl+Space 说明:内容助理.提供对方法,变量,参数,javadoc等得提示, 应运在多种场合,总之需要提示的时候可先按此快捷键. 注:避免输入法的切换设置与此设置冲突 (2)Ctrl ...
- Kinect for Windows SDK开发学习相关资源
Kinect for Windows SDK(K4W)将Kinect的体感操作带到了平常的应用学习中,提供了一种不同于传统的鼠标,键盘及触摸的无接触的交互方式,在某种程度上实现了自然交互界面的理想,即 ...
- 从Undo,Redo谈命令模式
一般的应用软件中,通常会提供Redo和Undo的操作,比如Paint.NET中的动作面板,Word中的撤销重做,一般我们按Ctrl-Z即可回退到上次操作. 要实现上面的这一功能,最直观的想法就是,我们 ...
- Got the Best Employee of the year 2015 Star Award
Got "The Best Employee of the year 2015 Star Award" from the company, thanks to all that h ...
- 查看html元素绑定的事件与方法的利器
WEB标准提倡结构.表现和行为相 分离,现在越来越多采用这种表现和行为的方式,但它也为我们开发调试带来一些问题,网页载入一堆JavaScript,,我们很难搞清楚最后在哪些元素的哪个动作绑定了事件,尤 ...
- easyui 数据库修改部分(基于数据添加逻辑功能修改)
{iconCls:'icon-edit',text:'修改', handler:function(){ type="edit"; //判断是否选中一条数据 var data = $ ...