Más contenido relacionado
再来了解文档回流(Reflow)
- 2. 国耻日 '918' 1931 年 9 月 18 日 ,小 RB 驻中国东北地区的关东军突然袭击沈阳,以武力攻击东北。日本制造“柳条湖事件”,发动了对中国东北的战争。天朝大国开始了屈辱的历史。。。 79 年后的今天,中国的领土主权尚无法保全;北有巨象俄毛子监视,东有倭寇尚在挑衅,西南有印度小三,东南有越南,菲利宾,马来西亚等小瘪三蠢蠢欲动。。。
- 4. 引子 话说两头,回到我们今天要探讨的话题; AJAX(Asynchronous JavaScript and XML) 是多种技术的综合,它使用 XHTML 和 CSS 标准化呈现,使用 DOM 实现动态显示和交互,使用 XMLHttpRequest 对象进行异步数据读取,使用 Javascript 绑定和处理所有数据。更重要的是它打破了使用页面重载的惯例技术组合。 AJAX 是一把双刃剑,在提供更为友好交互的同时,对页面的性能会造成影响; 对 DOM 的频繁操作,会引起 reflow (汗 .. 总算是见到它了)
- 7. 要提高页面性能,其实就是避免 reflow 的开销。那么,有哪些方面是需要 reflow 的呢? 2 。在编写一些常见的动态效果时,一般使用 CSS 的 display 来切换可见性。很不幸, 这也会产生 reflow. 把元素置为 display:none ,相当于把这个元素的 frame 销毁了, 再置回非 none 时,需要重新构造 frame ,这就产生了 reflow. 而另外一个切换 可见性的 属性 visibility 则不存在 reflow 问题,置为 visibility:hidden 的元素的 frame 并没有销毁, 需要显示的时候其实就是一个绘制(上面提到的动作第三步)过程而已,没有 reflow , 因此效率会更高。 在一些博客上看到有人说过,在 JavaScript 库/框架的源码,会发现它们大量使用 visibility 而不是 display (当然这个有待查究) ,道理应该如此。 1 。比如,未指定图片宽高的话,图片的载入会使页面 reflow, 因为要根据图片宽高来更新 frame 。 这里就有一个提高页面性能的小技巧:如果事先能够确定图片宽高的话,最好在 HTML 里写上。
- 9. 我们对页面的 DOM 的表现作出 css 的设定和对节点的结构改变 , 都会让浏览器需要按照这些改变 , 来重新计算 , 重新以对应的方式来呈现出来 . 例如我们中午去食堂排队吃饭 , 大厅里已经排了一条条长龙(粉蒸肉快没了) , 你很激动的发现 , 你排在第 5 位很快马上轮到自己了 , 正兴奋之时前面第 3 位插进一位凤姐 , 顿时你变成了 6 位 , 你前面的变成第 5 位… . 整个长龙的每个人的位置产生了变化 , 我们可以说 , 这个队伍 reflow 了。这样理解 , 要是必须给 reflow 安个中文名 , 我们把这过程会称之为 回流 吧。 或许这样讲更易理解
- 12. 如果加上这段 JavaScript, 当点击 a 标签时, 因为移除了 <P> 而发生的 reflow, 会触发他的 子标签和父级标签 都 reflow, 这里包括 (strong, div, body), 而对于兄弟标签如 <h5> 和 <ol>, 也会产生轻度的 reflow 从而就会触发页面的重新呈现 . <script type="text/javascript"> function $(id){return document.getElementById(id);} $( 'delGo' ).onclick=function(){ $( 'remove' ).parentNode.removeChild($( 'remove' )); return false;} </script> 如果在复杂的页面结构里频繁的进行这样的操作,可以想象很恐怖
- 15. <script> function $(id){return document.getElementById(id);} function addNode(){ var n = document.createElement( 'div' ); n.innerHTML = 'New Node'; $( 'test1' ).appendChild(n);} function modNode(){ $( 'test2' ).innerHTML = 'hello' ;} function delNode(){$( 'test3' ).parentNode.removeChild($( 'test3' ));} </script> <p id="test1" onclick="addNode()"> 这里是第 1 个节点 </p> <p id="test2" onclick="modNode()"> 这里是第 2 个节点 </p> <p id="test3" onclick="delNode()"> 这里是第 3 个节点 </p> 实例测试:
- 17. DAE 登场了: 我们来看看 dynaTrace 的情况,首先是一目了然的点击事件分布 增加节点: 修改节点: 删除节点: 图中的绿色部分表示的是 reflow 和 repaint (中文称为重绘,暂忽略)过程,其中比较短的绿条标示的 reflow 过程,后面长条部分表示的是 repaint 过程。从图中可以看出,对 DOM 节点的增删改都会造成 reflow 和 repaint ,由于改动小所以 reflow 消耗的时间很短,但是由于 repaint 是全局的,因此消耗的时间都比较长
- 18. 我们再来看看对 color 和 background-color 的修改【实例 test5.html test5-2.html 】 <p id=" colorNode "> 修改 DOM 元素 color 属性 </p> < script > function $(id){return document.getElementById(id);} var n = $( 'colorNode' ); n.style. color = 'red'; </ script > <p id=" colorNode "> 修改 DOM 元素 background-color 属性 </p> < script > function $(id){return document.getElementById(id);} var n = $( 'colorNode' ); n.style. backgroundColor = 'red'; </ script > 修改背景色也会造成 reflow 和 repaint 。经测试,只要是修改元素的 cssText 属性,不论它的值是什么,都会导致浏览器 reflow 或 repaint
- 19. window.resize 事件 >> 这里我们来看一个实例 test6.html 测试中的操作如下:缩小浏览器窗口 -> 放大浏览器窗口 -> 拖动页面滚动条至页面底部。 从图中可以看到 Resize 浏览器窗口以及拖动滚动条都会造成浏览器的 repaint ,而且 CPU 的消耗也比较大,尤其是拖动滚动条的时候
- 21. 1. resizing the window (在触发 window.resize 事件) 2. 改变字体 3. 增加或者删除样式文件 4. 内容的改变 ( 例如用户在 input 里面输入了内容 ) 5. 一些伪类的使用 ( 例如 a:hover) 6. 动态改变了一些 class 引用 7. 通过脚本改变 DOM( 例如使用 innerHTML 之类的 ) 8. 计算读取 offsetWidth 和 offsetHeight 等 ( 但经过测试并未发现会触发 reflow) 9. 设置标签的 style 属性值 哪些会引起 Reflow?
- 24. < script type="text/javascript"> function appendEveryTime (){ for( var i = 5000; i--; ){ var n = document. createElement ('div'); n.innerHTML = 'node ' + i; document.body. appendChild (n);/* 每次创建的新节点都 append 到文档 */ } } window. onload =appendEveryTime(); </ script > < script type="text/javascript"> function appendLast (){ var frag = document. createDocumentFragment (); for( var i = 5000; i--; ){ var n = document. createElement ('div'); n.innerHTML = 'node ' + i; frag. appendChild (n);/* 每次创建的节点先放入 DocumentFragment 中 */ } document.body.appendChild(frag); } window. onload =appendLast(); </ script >
- 25. 用 DAE 来观察的结果如: appendEveryTime appendLast appendLast 的性能无论是在 Javascript 的执行时间以及浏览器渲染时间方面都优于 appendEveryTime
- 26. That's all? 综合前面几个对 DOM 结构的增删改(当然加上一些前辈们总结的经验结果) >> 当然,我们并非反对在 Dom 的修改(有时这是必须的的操作); 我们怎样来避免或者说减少 reflow 对浏览器端造成影响?
- 28. 路漫漫其修远兮 吾将上下而求索 延伸阅读及参考资料: Notes on HTML Reflow (http://www.mozilla.org/newlayout/doc/reflow.html) Understanding Internet Explorer Rendering Behaviour (http://blog.dynatrace.com/2009/12/12/understanding-internet-explorer-rendering-behaviour/) EFFICIENT JAVASCRIPT (http://dev.opera.com/articles/view/efficient-javascript/?page=3#reflow) 网页优化 : 浏览器的 reflow 优化理论 (http://www.alixixi.com/web/a/2010062561095.shtml) 关于 reflow (http://www.blueidea.com/tech/web/2007/4950.asp)