Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

浅谈 Javascript 性能优化

8,037 views

Published on

improve javascript performance

Published in: Self Improvement
  • Hey guys! Who wants to chat with me? More photos with me here 👉 http://www.bit.ly/katekoxx
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • 精辟、明了,slides也做得漂亮。
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • 温习
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • 收藏。
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • 分享了 哈哈
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

浅谈 Javascript 性能优化

  1. 1. 浅谈 JavaScript 性能优化<br />龙刚 (@RainoXu)TaobaoUED<br />www.rainoxu.com<br />
  2. 2. 优化 JavaScript性能,使它运行足够快一个关键因素:运行的时间<br />
  3. 3. 响应时间与用户的体验<br />0.1s<br />用户觉得很流畅<br />1.0s<br />用户的操作可能偶尔受到影响,并且用户已经能感觉到有些不流畅<br />10s<br />对用户的影响比较严重,需要相应的进度提示。用户也会有一些沮丧<br />
  4. 4. What To Do && How To Do?<br />
  5. 5. 管理作用域<br />操作数据<br />流控制<br />Reflow<br />DOM操作<br />长时间运行的脚本处理<br />
  6. 6. 管理作用域<br />function add(num1, num2){<br />return num1 + num2; <br />} <br />var result = add(5, 10);<br />
  7. 7. 使用局部变量<br />局部变量存在于活动对象中,解析器只需查找作用域中的单个对象<br />var a = 1;<br />function test(){<br /> //对变量a进行一系列操作<br />}<br />function test2(){<br />var a = 1;<br /> //对变量a进行一系列操作<br />}<br />
  8. 8. 另一个例子<br />(function(win, S, undefined) {<br /> ...<br /> ...<br />var doc = win['document'], loc = location,<br /> EMPTY = '',<br /> ...<br /> ...<br />})(window, 'KISSY');<br />
  9. 9. 数据操作<br />
  10. 10. 使用局部变量,它是最快的缓存频繁使用的对象、数组及相关的属性值<br />
  11. 11. obj.name比obj.xxx.name访问更快,访问属性的速度,与其在对象中的深度有关<br />“ . ”操作的次数直接影响着访问对象属性的耗时<br />varobjName = obj.name;<br />
  12. 12. KISSY.add('switchable', function(S, undefined) {<br />var DOM = S.DOM, Event = S.Event,<br /> ...<br /> ...<br />});<br />
  13. 13. function process(data){<br /> if (data. count> 0){<br /> for(vari = 0; i < data.count; i++){<br />processData(data.item[i]);<br /> } <br /> }<br />}<br />
  14. 14. function process(data){<br />var count = data.count;<br /> if (count > 0){<br /> for(vari = 0; i < count ; i++){<br />processData(data.item[i]);<br /> } <br /> }<br />}<br />
  15. 15. NodeList<br />不直接操作NodeList,将其转换成静态数组后再使用<br />方法:<br />Array.prototype.slice.call() => 标准浏览器<br />逐个拷贝到一个新数组中 => For IE<br />
  16. 16. 大部分JS库都有提供将Array-Like的对象转变成Array的方法(如KISSY提供的makeArray()方法);部分JS库在返回元素集合时,已预处理成Array(例子:YUI的DOM相关操作方法)<br />
  17. 17. 遍历NodeList时,不做对当前NodeList相关结构有影响的DOM操作,并且如之前所提到的,要缓存一些频繁使用到的属性值,以避免杯具发生。<br />
  18. 18. vardivs = document.getElementsByTagName('DIV');<br /> //假定页面中有div,所以divs.length是大于0的<br />for (varidx = 0; idx < divs.length; idx++){<br />document.body.appendChild(<br />//杯具悄然而置<br />document.createElement('DIV')<br /> );<br /> console.info(divs.length);<br /> }<br />
  19. 19. 杯具的原因?<br />通过getElementsByTagName()获取得到的是一个LiveNodeList的引用,任何对其相关的DOM操作都会立即反应在这个NodeList上面<br />通过不断地往document.body下插入div 节点,for循环的终止条件(div.length也随之改变)失效,陷入死循环。<br />
  20. 20. Live NodeListvs Static NodeList<br />理论上,静态的东西应该是最快的,但是实际情况是,Live NodeList更快。<br />
  21. 21. Live NodeListvs Static NodeList<br />原因:目前市场上的浏览器,对Live NodeList做了缓存<br />
  22. 22. Live NodeListvs Static NodeList<br />结论:优先使用Live NodeList,通过选择器获取以后,再进一步转换成数组来使用。这也是目前许多JS库在使用的方案。<br />
  23. 23. DOM操作<br />指明操作DOM的context<br />YUI:<br /> Array getElementsByClassName ( className , tag , root , apply , o , overrides ) <br />KISSY:<br /> Array<HTMLElement> query ( selector, context )<br />即便是用原生的JS,也应该指明:<br />context.getElementsByTagName()<br />
  24. 24. DOM操作<br />增删、修改节点<br />使用DocumentFragment<br />使用cloneNode()复制一份目标节点来处理<br />如果是直接修改DOM,请先将其display:none;<br />
  25. 25. 一个方法尽可能只做一件事<br />拆分功能,让一个方法只做一件事,通过不断地调用方法来实现复杂功能,但是,这些简单方法要避免相互交叉调用。<br />
  26. 26. KISSY Poster中的一些方法拆分<br />
  27. 27. KISSY Poster中的一些方法拆分<br />
  28. 28. Be Lazy<br />使脚本尽可能少地运行,或者不运行。<br />
  29. 29. 短路表达式应用:如 a && b || c<br />基于事件去写相应的处理方法<br />惰性函数<br />
  30. 30. 合理地使用事件代理<br />DOM与事件处理<br />
  31. 31. 为元素绑定事件<br />Event.on ( target, type, fn, scope )<br />
  32. 32. 事件代理的原理<br />冒泡<br />捕获<br />
  33. 33. 事件代理应用的场景?<br />
  34. 34.
  35. 35. Event.on(container, ‘click’, function (ev){<br />var target = ev.target();<br /> switch(target.className){//或者可以是nodeName<br /> ...<br /> ...<br /> ...<br /> }<br />});<br />
  36. 36. 流控制<br />
  37. 37. if(...){<br />}elseif(...){<br />}elseif(...){<br />}elseif(...){<br />}elseif(...){<br />}elseif(...){<br />}else{<br />}<br />
  38. 38. 在if语句中,将经常会发生的条件,放在靠上的位置<br /> if的条件为连续的区间时,可以使用二分法的方式来拆分<br />较多离散值的判断,可以使用switch来替代<br />使用数组查询的方式<br />
  39. 39. 要注意隐式的类型转换<br />varfoo = 0;<br /> if(foo == false){<br /> ...<br /> }<br />
  40. 40. 小心递归!<br />
  41. 41. function recurse(){<br />recurse();<br />}<br />recurse();//又是一个杯具<br />
  42. 42. 浏览器对调用栈的最大限度的定义各不一样<br />递归的相互调用、自身调用可能触发浏览器的调用栈的最大极限<br />
  43. 43. Reflow<br />
  44. 44. 主要引起Reflow的因素<br />操作DOM树<br />与布局有关的样式改变<br />改变className<br />窗口大小调整<br />字休大小<br />
  45. 45. 优化运行时间较长的脚本<br />
  46. 46. 原因:<br />大量DOM操作<br />过多的循环与递归<br />解决问题的最佳实践:<br />使用定时器<br />
  47. 47. 最后,优化原则?<br />
  48. 48. 2/8原则<br />考虑大多数情况,极端情况,有能力则兼顾之,适当取舍<br />
  49. 49. 性能与可维护性权衡之一原则<br />
  50. 50. 站在巨人的肩膀上,看得更远<br />YAHOO的前端小组、JohnResig、NicholasC.Zakas等都已经总结了很多有用的性能优化方面的经验,以他们的研究成果做为优化时的参考。<br />
  51. 51. 好的编程习惯<br /><ul><li>不以善小而不为
  52. 52. 思先于行,不必过早优化</li></li></ul><li>最后,感谢玉伯、云谦、圆心、龙俊、释然对我此次的分享提供了许多帮助和建议。<br />
  53. 53. Question?<br />

×