YAOHAIXIAO.COM

Focus on front end technoloy

Douglas Crockford 谈 Ajax 性能

这是Douglas Crockford在圣诞节前的一个讲座。我觉得对于前端工程师来说算是一个“新年大片”。英文好的建议直接去看原文http://ericmiraglia.com/blog/?p=140感谢Eric Miraglia提供了完整的文字记录。

Crock先用《记忆碎片》这部电影作为引子。我还没看过,一定要找来看看。

如果要向不太了解JSON的解释JSON为什么好Crock这句话说的很清楚“A JSON message is less work for the server to generate, it moves much faster on the wire because it’s smaller, it’s less work for the browser to parse and render than an HTML document.”

“The page is an application with a data connection to a server.”Crock对Ajax Revolution标题的注解。他提到“the client dose not need a copy of the database. it just needs, at any moment, just enough information to serve the user”,后端把所有数据都交给前端处理,后端是省事了,而浏览器端的性能则变的极差。“the client and the server are in a dialog, and we make the messages between them be as small as possible”,这是一个关键原则。just-in-time data delivery(按需传输数据)。

这些道理其实尽人皆知,但在设计复杂的应用时,在进行多人协作的项目时,仍然会犯这样的错误。为什么?因为如果真的要实现一个客户端和服务器端的高效对话,服务器端的设计就会变的复杂,我充分理解后端工程师也要考虑他们的问题。但为了更高效率,后端多花一些心思是值得的,因为目前浏览器还是一个非常低效的应用平台(这也是Google推出Chrome的原因),存在显著的安全问题和性能问题。

Crock举的这个memoizer(缓存器)的例子非常经典:

   var fibonacci = function(n){
   return n < 2 ? n :
   fibonacci(n - 1) + fibonacci(n - 2);
   };
   fibonacci(40);
   执行自己 331,160,280 次
 
   var memoizer = function(memo, fundamental){
   var shell = function(n){
   var result = memo[n];
   if(typeof result !== 'number'){
   result = fundamental(shell, n);
   memo[n] = result;
   }
   return result;
   }
   return shell;
   }
 
   var fibonacci = memoizer([0, 1], function(recur, n){
   return recur(n - 1) + recur(n - 2);
   });

优化后的程序仅执行了38次。”the key to optimization is work avoidance.” (优化的关键是“逃避工作”的技巧)

Crock提到两种优化思路:streamline和special casing

streamline(简化为使效率更高):更换算法(选择更好的算法)、逃避工作、清除冗余代码(项目反复修改每次只是增加,往往忽略清除没用的代码)而且”These things are always good to do”这些事情应该一直去做而不是等到出现性能问题之后再解决。

special casing理解成特别包装更好一些。为了解决某些特别需求在原有代码基础上所做的包装,优其是对公共组件。会导致冗余代码越来越多,增加代码的 size,同时还会增加更多的测试路径(如果代码要进行白盒测试,无疑测试成本将增加很多)。要知道产品的需求永远是善变的。处理这种特殊需求可以写一些 “适配器”或“桥接器”,不用的话就直接拿掉。

“Avoid unnecessary displays or animation”很多产品经理认为花哨的交互就是好的用户体验,或者就是认为它够shiny,殊不知它带来的负面影响远比它的作用要大的多。 Crock是这么说的“A ‘wow’ effect is definitely worthwhile if it improves the user’s productivity, or improves the value of the experience to user.If it’s there just to show that we can do that, I think it’sa waste of our time, it’sa waste of the user’s time.”(译:如果这样做能提高用户的生产力或提升用户体验的价值,一个‘喔噻’的效果是价得的。但如果它的存在只是为了表明,我们能够做到这一点,我认为这是浪费我们的时间,这是浪费用户的时间)

重点解决影响最大的性能问题。看似费话,其实在开发中避重就轻的事没少干。关键首先要准确的判断出哪些环节是最大的症结所在。The bottleneck tends to be the DOM interface — DOM is a really inefficient API.(译: 瓶颈倾向于DOM接囗 - DOM是一个相当低效的API),还会有reflow计算的问题。“So touch the DOM lightly, if you can.”怎么才能“touch lightly”,Crock告诉我们两个技巧:一个是在创建的结点添加到DOM树上之前对其进行操作,这样不会有回流计算的问题。二是用 innerHTML,它只会跟DOM发生一次关系。

   var d = document.createElement("div");
   d.style.height = '100px';
   d.style.border = '1px solid red';
   d.style.color = 'green';
   ...(该办的事先办完)...
   //最后再添加到dom树中
   document.body.appendChild(d);

“Don’t Tune For Quirks”不要调那些浏览器的怪异问题。建议首先是尽量绕开这些quirks,虽然通过一些技巧可以解决这些问题,但也许在其它浏览器上性能就会变差。而且当浏览器升级后修复了这个问题,之前所做的优化可能会变得更糟。Crock建议不做短期优化。

短短三十多分钟的讲座细细品味的话可以引出很多思考。简单总结一下:

  • 一 、是客户端要轻。程序不要臃肿,不要把所有数据都交给前端处理
  • 二 、是代码是基础。寻求更好的算法,更好的设计模式
  • 三 、是借助工具,不凭直觉
  • 四 、是要抓重点。揪住主要问题解决
  • 五、 是DOM操作是瓶颈
  • 六、 是不要做短期优化

版权所有 © 2008-2010 yaohaixiao.com, 保留一切权利。    ICP备案:鄂ICP备08000339号