reflow
去听了牛人dbaron的一个Web Page Layout/Display in Mozilla 讲座(via)。讲的东西对我一个只会HTML, CSS和JavaScript的人来说很底层,所以效果也比较“和谐”,只是大致了解了mozilla的CSS渲染源码分布位置和渲染流程而已。
讲座提到了reflow(如何翻译呢?又是一个问题)这个东东。之前对reflow有所闻,能经常从某些大牛的幻灯中提到,提高页面渲染的性能,需尽量避免reflow. 那么reflow是什么东西呢?它又是如何影响页面性能的?事后去问了一下dbaron(呵呵,我口语彻底不行,加上心理素质,最后是把问题写下来给他看),豁然开朗也。
在CSS规范中有一个渲染对象的概念,通常用一个盒子(box, rectangle)来表示。mozilla通过一个叫frame的对象对盒子进行操作。frame主要的动作有三个:
- 构造frame, 以建立对象树(DOM树)
- reflow, 以确定对象位置,或者是调用mozilla的Layout(这里是指源码的实现)
- 绘制,以便对象能显示在屏幕上
总的来说,reflow就是载入内容树(在HTML中就是DOM树)和创建或更新frame结构的响应的一种过程。
要提高页面性能,其实就是避免reflow的开销。那么,有哪些方面是需要reflow的呢?比如,未指定图片宽高的话,图片的载入会使页面reflow, 因为要根据图片宽高来更新frame。这里就有一个提高页面性能的小技巧:如果事先能够确定图片宽高的话,最好在HTML里写上。
在编写一些常见的动态效果时,一般使用CSS的display来切换可见性。很不幸,这也会产生reflow. 把元素置为display:none,相当于把这个元素的frame销毁了,再置回非none时,需要重新构造frame,这就产生了reflow. 而另外一个切换可见性的属性visibility则不存在reflow问题,置为visibility:hidden的元素的frame并没有销毁,需要显示的时候其实就是一个绘制(上面提到的动作第三步)过程而已,没有reflow,因此效率会更高。如果你看过一些JavaScript库/框架的源码,会发现它们大量使用visibility而不是display,道理应该如此。

September 9th, 2007 at 09:48
长知识了。
对于我来说,可见的改变就写HTML时,尽量给图片写上宽和高。
September 9th, 2007 at 18:54
[...] 下面是一点技术摘要,来自:http://realazy.org/blog/2007/09/09/reflow/ [...]
September 9th, 2007 at 20:14
visibility:hidden貌似只是不显示,实际上还是占了位置
而display:none则不会出现占位的问题哈
September 9th, 2007 at 20:39
@炎妖儿 不错,所以得看具体情况而用,不是说非得使用
visibilty而不用display, 两者还是有自己的不同用途的。但是,有一种情况,
visibilty和display都不会占位,那就是绝对/固定定位的情况下。所谓相机而动是也。September 9th, 2007 at 21:10
@realazy:绝对/固定定位的情况下其实也不是完全不占位的。。。在z-index相同,位置差不多的情况下还是会看到visibilty的占位哈。。。俺有点钻牛角间。。。嘎嘎
平时一般的文本隐藏用text-indent:-999em比较多,据说visibilty和display用多了有seo作弊的嫌疑
September 10th, 2007 at 08:51
长见识了,谢谢分享
September 10th, 2007 at 09:24
( ^_^ !!!) 之前还一直用CSS来控制图片SIZE…
用overflow:hidden; + height:1px; 不知道会否出现reflow的问题!
September 10th, 2007 at 09:29
[...] 文来源:http://realazy.org/blog/2007/09/09/reflow/ [...]
September 11th, 2007 at 14:17
very good
September 11th, 2007 at 14:37
看了你和炎妖儿的讨论,得出一个结论:
>>>> 对于一些局部UI,通过visibilty、z-index和非online布局方式,可以优化display:none
哈哈
September 11th, 2007 at 14:39
题外话:MyBlogLog,不错啊。从抓虾看不到这些:D
September 13th, 2007 at 13:07
这篇文章不错,又学到了新知识^^
September 13th, 2007 at 16:26
的确,以前做页面只考虑表面文件大小和代码结构的优化问题,没往CSS渲染这层考虑,哈哈,很不错哟~~
September 13th, 2007 at 17:17
谢谢realazy 又给我们上了一节课
September 14th, 2007 at 17:26
哪问一下,如果两层div,第一层设置了宽度譬如100px,里面一层没有设置宽度值,那么是否会影响页面渲染速度呢
September 26th, 2007 at 19:04
非常不错的文章,在其中受益不少,感谢至上.
October 1st, 2007 at 21:31
(呵呵,我口语彻底不行,加上心理素质,最后是把问题写下来给他看)
好吧,我改天去回龙观把你拉出来一起练习^_^
October 9th, 2007 at 14:11
gooooooooood
October 26th, 2007 at 13:41
每次直接改动tag的style就会导致reflow, 所以推荐先cache再改变:
var st = dom.get(’targetId’).style;
st.background = “#fff”;
…
这样就可以避免reflow, 同样访问node的offsetWidth或offsetHeight也会导致reflow,也是先cache
当时只知道这个having minimal reflows的原则,不清楚这个原理,感谢你的分享
November 2nd, 2007 at 13:09
这样哇
学习了
@Kejun
好复杂哈
呵呵
我恶补一下
……
又是硕大的提交按钮儿
November 3rd, 2007 at 19:00
树状菜单不需使用reflow吧,不止各位有何高见?
December 29th, 2007 at 17:03
学习到了
January 15th, 2008 at 21:02
1,reflow
2,img height
3,display/visibility
February 5th, 2008 at 13:22
这个文章没结论?
May 29th, 2008 at 00:50
[...] reflow是个神奇的东西,之前Realazy说到过这个reflow,我摘出其中的重点: 在CSS规范中有一个渲染对象的概念,通常用一个盒子(box, rectangle)来表示。mozilla通过一个叫frame的对象对盒子进行操作。frame主要的动作有三个: [...]
August 22nd, 2008 at 10:35
[...] 下面是一点技术摘要,来自:http://realazy.org/blog/2007/09/09/reflow/ [...]