SlideShare una empresa de Scribd logo
1 de 29
再来了解 Reflow 提高 web 前端性能系列之 Alex,http://ued.iciba.com/, 18/9/2010
国耻日 '918' 1931 年 9 月 18 日 ,小 RB 驻中国东北地区的关东军突然袭击沈阳,以武力攻击东北。日本制造“柳条湖事件”,发动了对中国东北的战争。天朝大国开始了屈辱的历史。。。 79 年后的今天,中国的领土主权尚无法保全;北有巨象俄毛子监视,东有倭寇尚在挑衅,西南有印度小三,东南有越南,菲利宾,马来西亚等小瘪三蠢蠢欲动。。。
我们能做什么? 支持武力解决所有领土争端,尤为突出的为南中国海(个人意见,如果需要我愿为解放军当炮灰) 提高自身能力,认真对待工作中每件事,做的更好
引子 话说两头,回到我们今天要探讨的话题; AJAX(Asynchronous JavaScript and XML) 是多种技术的综合,它使用 XHTML 和 CSS 标准化呈现,使用 DOM 实现动态显示和交互,使用 XMLHttpRequest 对象进行异步数据读取,使用 Javascript 绑定和处理所有数据。更重要的是它打破了使用页面重载的惯例技术组合。 AJAX 是一把双刃剑,在提供更为友好交互的同时,对页面的性能会造成影响; 对 DOM 的频繁操作,会引起 reflow (汗 .. 总算是见到它了)
what ? ,[object Object]
[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
要提高页面性能,其实就是避免 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 里写上。
[object Object],[object Object],您是怎么理解的? 来自 Alex 的白话:
我们对页面的 DOM 的表现作出 css 的设定和对节点的结构改变 ,  都会让浏览器需要按照这些改变 ,  来重新计算 ,  重新以对应的方式来呈现出来 . 例如我们中午去食堂排队吃饭 ,  大厅里已经排了一条条长龙(粉蒸肉快没了) ,  你很激动的发现 ,  你排在第 5 位很快马上轮到自己了 ,  正兴奋之时前面第 3 位插进一位凤姐 ,  顿时你变成了 6 位 ,  你前面的变成第 5 位… .  整个长龙的每个人的位置产生了变化 ,  我们可以说 ,  这个队伍 reflow 了。这样理解 ,  要是必须给 reflow 安个中文名 , 我们把这过程会称之为 回流 吧。 或许这样讲更易理解
So,More? 接下来,且看一小实例  >>
[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],<style type=&quot;text/css&quot;> .main{border:3px solid #cccccc;width:300px;padding:20px;} h4,h5,ol{border:2px solid #666666;} p{border:2px dotted #cccccc;} </style>
如果加上这段 JavaScript, 当点击 a 标签时, 因为移除了 <P> 而发生的 reflow,  会触发他的 子标签和父级标签 都 reflow,  这里包括 (strong, div, body),  而对于兄弟标签如 <h5> 和 <ol>,  也会产生轻度的 reflow 从而就会触发页面的重新呈现 . <script type=&quot;text/javascript&quot;> function $(id){return document.getElementById(id);} $( 'delGo' ).onclick=function(){ $( 'remove' ).parentNode.removeChild($( 'remove' )); return false;} </script> 如果在复杂的页面结构里频繁的进行这样的操作,可以想象很恐怖
And ? 让我们来看看 reflow 到底长啥样儿? >>
DynaTrace >> ‘ 工欲善其事 必先利其器’ 介绍一款强大的性能分析工具先 --dynaTrace ,[object Object],[object Object],NEXT>>
<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=&quot;test1&quot; onclick=&quot;addNode()&quot;> 这里是第 1 个节点 </p> <p id=&quot;test2&quot; onclick=&quot;modNode()&quot;> 这里是第 2 个节点 </p> <p id=&quot;test3&quot; onclick=&quot;delNode()&quot;> 这里是第 3 个节点 </p> 实例测试:
再来 DW CS4 实时代码功能,来监控到 DOM 的变化。。。
DAE 登场了: 我们来看看 dynaTrace 的情况,首先是一目了然的点击事件分布 增加节点: 修改节点: 删除节点: 图中的绿色部分表示的是 reflow 和 repaint (中文称为重绘,暂忽略)过程,其中比较短的绿条标示的 reflow 过程,后面长条部分表示的是 repaint 过程。从图中可以看出,对 DOM 节点的增删改都会造成 reflow 和 repaint ,由于改动小所以 reflow 消耗的时间很短,但是由于 repaint 是全局的,因此消耗的时间都比较长
我们再来看看对 color  和  background-color 的修改【实例 test5.html test5-2.html 】 <p id=&quot; colorNode &quot;> 修改 DOM 元素 color 属性 </p> < script > function $(id){return document.getElementById(id);} var n = $( 'colorNode' ); n.style. color  = 'red'; </ script > <p id=&quot; colorNode &quot;> 修改 DOM 元素 background-color 属性 </p> < script > function $(id){return document.getElementById(id);} var n = $( 'colorNode' ); n.style. backgroundColor  = 'red'; </ script > 修改背景色也会造成 reflow 和 repaint 。经测试,只要是修改元素的 cssText 属性,不论它的值是什么,都会导致浏览器 reflow 或 repaint
window.resize 事件 >>  这里我们来看一个实例  test6.html 测试中的操作如下:缩小浏览器窗口 -> 放大浏览器窗口 -> 拖动页面滚动条至页面底部。 从图中可以看到 Resize 浏览器窗口以及拖动滚动条都会造成浏览器的 repaint ,而且 CPU 的消耗也比较大,尤其是拖动滚动条的时候
来个小的总结吧 属性太多,不再逐个来测试,还是承前启后吧; 这里有译自一位大牛的测试结果  >>
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?
HOW? 如何优化你的脚本来减少 reflow?
再来看一个小实例吧 我们需要创建多个 DOM 节点【 test3.html &&test4.html 】
< script  type=&quot;text/javascript&quot;> 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=&quot;text/javascript&quot;> 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 >
用 DAE 来观察的结果如: appendEveryTime appendLast appendLast 的性能无论是在 Javascript 的执行时间以及浏览器渲染时间方面都优于 appendEveryTime
That's all? 综合前面几个对 DOM 结构的增删改(当然加上一些前辈们总结的经验结果) >> 当然,我们并非反对在 Dom 的修改(有时这是必须的的操作); 我们怎样来避免或者说减少 reflow 对浏览器端造成影响?
我们应该尽量这样去做 ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],这里归纳了 8 条法则 ( 当然并非全部,却具 代表性 )
路漫漫其修远兮 吾将上下而求索 延伸阅读及参考资料: 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)
Thank you!

Más contenido relacionado

Destacado

Destacado (11)

Joining vocabulary - Vocabulari de processos d'unió - Vocabulario de procesos...
Joining vocabulary - Vocabulari de processos d'unió - Vocabulario de procesos...Joining vocabulary - Vocabulari de processos d'unió - Vocabulario de procesos...
Joining vocabulary - Vocabulari de processos d'unió - Vocabulario de procesos...
 
Aprende a hacer tus procedimientos de soldeo. Nivel 1 (12/16)
Aprende a hacer tus procedimientos de soldeo. Nivel 1 (12/16) Aprende a hacer tus procedimientos de soldeo. Nivel 1 (12/16)
Aprende a hacer tus procedimientos de soldeo. Nivel 1 (12/16)
 
Aprende a hacer tus procedimientos de soldeo. Nivel 2 (02/17)
Aprende a hacer tus procedimientos de soldeo. Nivel 2 (02/17)Aprende a hacer tus procedimientos de soldeo. Nivel 2 (02/17)
Aprende a hacer tus procedimientos de soldeo. Nivel 2 (02/17)
 
Jornada Tècnica ITCS20è aniversari - patrocinadors
Jornada Tècnica ITCS20è aniversari - patrocinadors Jornada Tècnica ITCS20è aniversari - patrocinadors
Jornada Tècnica ITCS20è aniversari - patrocinadors
 
Examen visual aplicado a las uniones soldadas. Nivel 2 (09/16)
Examen visual aplicado a las uniones soldadas. Nivel 2 (09/16) Examen visual aplicado a las uniones soldadas. Nivel 2 (09/16)
Examen visual aplicado a las uniones soldadas. Nivel 2 (09/16)
 
Cualificación de soldadores según EN ISO 9606-1. Nivel 1 (10/16)
Cualificación de soldadores según EN ISO 9606-1. Nivel 1 (10/16) Cualificación de soldadores según EN ISO 9606-1. Nivel 1 (10/16)
Cualificación de soldadores según EN ISO 9606-1. Nivel 1 (10/16)
 
Introducción al cálculo de uniones soldadas (03/17)
Introducción al cálculo de uniones soldadas (03/17) Introducción al cálculo de uniones soldadas (03/17)
Introducción al cálculo de uniones soldadas (03/17)
 
Ensayo macrográfico de uniones soldadas (DTAw) (04/17)
Ensayo macrográfico de uniones soldadas (DTAw) (04/17) Ensayo macrográfico de uniones soldadas (DTAw) (04/17)
Ensayo macrográfico de uniones soldadas (DTAw) (04/17)
 
Ingeniero Internacional de Soldadura (IWE) (11/17)
Ingeniero Internacional de Soldadura (IWE) (11/17) Ingeniero Internacional de Soldadura (IWE) (11/17)
Ingeniero Internacional de Soldadura (IWE) (11/17)
 
Representación simbólica de soldadura en los planos (01/17)
Representación simbólica de soldadura en los planos (01/17) Representación simbólica de soldadura en los planos (01/17)
Representación simbólica de soldadura en los planos (01/17)
 
Examen visual aplicado a las uniones soldadas. Nivel 1 (VT1w) (01/17)
Examen visual aplicado a las uniones soldadas. Nivel 1 (VT1w) (01/17)Examen visual aplicado a las uniones soldadas. Nivel 1 (VT1w) (01/17)
Examen visual aplicado a las uniones soldadas. Nivel 1 (VT1w) (01/17)
 

再来了解文档回流(Reflow)

  • 1. 再来了解 Reflow 提高 web 前端性能系列之 Alex,http://ued.iciba.com/, 18/9/2010
  • 2. 国耻日 '918' 1931 年 9 月 18 日 ,小 RB 驻中国东北地区的关东军突然袭击沈阳,以武力攻击东北。日本制造“柳条湖事件”,发动了对中国东北的战争。天朝大国开始了屈辱的历史。。。 79 年后的今天,中国的领土主权尚无法保全;北有巨象俄毛子监视,东有倭寇尚在挑衅,西南有印度小三,东南有越南,菲利宾,马来西亚等小瘪三蠢蠢欲动。。。
  • 4. 引子 话说两头,回到我们今天要探讨的话题; AJAX(Asynchronous JavaScript and XML) 是多种技术的综合,它使用 XHTML 和 CSS 标准化呈现,使用 DOM 实现动态显示和交互,使用 XMLHttpRequest 对象进行异步数据读取,使用 Javascript 绑定和处理所有数据。更重要的是它打破了使用页面重载的惯例技术组合。 AJAX 是一把双刃剑,在提供更为友好交互的同时,对页面的性能会造成影响; 对 DOM 的频繁操作,会引起 reflow (汗 .. 总算是见到它了)
  • 5.
  • 6.
  • 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 里写上。
  • 8.
  • 9. 我们对页面的 DOM 的表现作出 css 的设定和对节点的结构改变 , 都会让浏览器需要按照这些改变 , 来重新计算 , 重新以对应的方式来呈现出来 . 例如我们中午去食堂排队吃饭 , 大厅里已经排了一条条长龙(粉蒸肉快没了) , 你很激动的发现 , 你排在第 5 位很快马上轮到自己了 , 正兴奋之时前面第 3 位插进一位凤姐 , 顿时你变成了 6 位 , 你前面的变成第 5 位… . 整个长龙的每个人的位置产生了变化 , 我们可以说 , 这个队伍 reflow 了。这样理解 , 要是必须给 reflow 安个中文名 , 我们把这过程会称之为 回流 吧。 或许这样讲更易理解
  • 11.
  • 12. 如果加上这段 JavaScript, 当点击 a 标签时, 因为移除了 <P> 而发生的 reflow, 会触发他的 子标签和父级标签 都 reflow, 这里包括 (strong, div, body), 而对于兄弟标签如 <h5> 和 <ol>, 也会产生轻度的 reflow 从而就会触发页面的重新呈现 . <script type=&quot;text/javascript&quot;> function $(id){return document.getElementById(id);} $( 'delGo' ).onclick=function(){ $( 'remove' ).parentNode.removeChild($( 'remove' )); return false;} </script> 如果在复杂的页面结构里频繁的进行这样的操作,可以想象很恐怖
  • 13. And ? 让我们来看看 reflow 到底长啥样儿? >>
  • 14.
  • 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=&quot;test1&quot; onclick=&quot;addNode()&quot;> 这里是第 1 个节点 </p> <p id=&quot;test2&quot; onclick=&quot;modNode()&quot;> 这里是第 2 个节点 </p> <p id=&quot;test3&quot; onclick=&quot;delNode()&quot;> 这里是第 3 个节点 </p> 实例测试:
  • 16. 再来 DW CS4 实时代码功能,来监控到 DOM 的变化。。。
  • 17. DAE 登场了: 我们来看看 dynaTrace 的情况,首先是一目了然的点击事件分布 增加节点: 修改节点: 删除节点: 图中的绿色部分表示的是 reflow 和 repaint (中文称为重绘,暂忽略)过程,其中比较短的绿条标示的 reflow 过程,后面长条部分表示的是 repaint 过程。从图中可以看出,对 DOM 节点的增删改都会造成 reflow 和 repaint ,由于改动小所以 reflow 消耗的时间很短,但是由于 repaint 是全局的,因此消耗的时间都比较长
  • 18. 我们再来看看对 color 和 background-color 的修改【实例 test5.html test5-2.html 】 <p id=&quot; colorNode &quot;> 修改 DOM 元素 color 属性 </p> < script > function $(id){return document.getElementById(id);} var n = $( 'colorNode' ); n.style. color = 'red'; </ script > <p id=&quot; colorNode &quot;> 修改 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?
  • 23. 再来看一个小实例吧 我们需要创建多个 DOM 节点【 test3.html &&test4.html 】
  • 24. < script type=&quot;text/javascript&quot;> 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=&quot;text/javascript&quot;> 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 对浏览器端造成影响?
  • 27.
  • 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)