高性能的Ajax应用-Julien Lecomte

转载 2011年01月19日 18:22:00

第1部分 高性能的开发

1.为高性能计划和设计
-从每一天开始就要计划高性能
-跟产品经理和设计师紧密的合作
-理解设计的基本原理
-设计和性能之前做解释和权衡
-提供选择和展示各种可能(原型)
-挑战自己,实现有挑战性的设计(不要只说“不”)
-为了简化设计和交互,有时候需要妥协

2.高性能工程开发:一些基本规则
-少就是多。不要做任何不必要的事。直到变得绝对重要,否则不要做。
-打破规则。只能在迫不得以的情况下,才能妥协并打破最佳做法。
-在提升可以感觉到的性能上下功夫。

3.衡量性能
-使用用户真实环境测试
-在开发中,profile你的代码
-使用自动的profiling/性能测试
-保持功能执行的历史数据
-在产品中考虑保留一些(少量的)profiling代码

第2部分 高性能的页面下载

1.Yahoo!的14条性能原则
一个页面工作于3(有时是重叠的)个阶段-下载,渲染,运行。14条原则大部分作用于第1个阶段。

2.资源优化
-最小化CSS和Javascript文件。推荐使用YUI Compressor(http://developer.yahoo.com/yui/compressor)压缩。远离那些所谓的先进的压缩方案,如Packer。
-合并CSS和Javascript文件。在发布的时候合并(http://www.julienlecomte.net/blog/2007/09/16)或在运行的时候合并。
-优化图片资源。如:PngCrush(http://pmt.sourceforge.net/pngcrush)、PngOptimizer(http://psydk.org/PngOptimizer.php)等。

3.减小非压缩代码的大小
-下载和解析HTML、CSS、Javascript代码的成本是很高的。
-用简练写法和写更少的代码
-用好Javascript库
-在考虑将大的Javascript文件拆成小的文件(bundle)时,解析和编译脚本时要花费大量额外的时间
-按需下载代码(HTML、CSS、Javascript),如,Lazy Loading
* 参见,http://ajaxpatterns.org/On-Demand_Javascript
* 使用 YUI Loader
* Dojo的package system
* JSAN的Import System

4.优化初始渲染(1):综合技巧
-Consider rendering the first view on the server
-关闭你的HTML标签提高解析速度。参见http://msdn2.microsoft.com/en-us/library/ms533020.aspx#Close_Your_Tags
-考虑尽早缓存。
-下载基本的资源,延迟或按需下载其他资源。使用YUI ImageLoader。

5.优化初始渲染(2):不要一直等onload
-大部分DOM操作可以在onload事件触发前完成
-如果你需要控制你的初始化代码,可以直接写在<script>里,并把它放在靠近</body>的位置
-否则,使用YUI事件组件中的onDOMReady方法
YAHOO.util.Event.onDOMReady(function () {
// Do something here...
// e.g., attach event handlers.
});

6.优化初始渲染(3):在页面下载后,再下载脚本。
-一个好的网站应该在Javascript失效下功能也应该是完整的
-因此,你可以延迟下载脚本
-这样做对下载其他资源(样式表、图片等)是有好处的
-这样做使网站下载更快

7.优化初始渲染(4):有条件的预下载
-预下载潜在的资源(Javascript、CSS、图片等)真的可以增强用户体验。
-可是,在什么时候进行功妙的预下载是关键,否则,预下载会影响用户体验。
-参见http://www.sitepoint.com/article/web-site-optimization-steps/3
-参见http://search.yahoo.com


第3部分 高性能的Javascript

1.减少符号查寻(1):范围链
-每次访问变量时都会执行查寻
-变量从当前范围向上执行查寻
-因此,无论何时都在相同范围中声明和使用变量
-完全不要使用with,它会阻止编译器生成代码时访问本地变量的速度(因为首先要遍历原型链,然后是范围链等)
-缓存外部变量到本地变量。
不好的写法:
var arr = ...;
var globalVar = 0;
(function () {
var i;
for (i = 0; i < arr.length; i++) {
globalVar++;
}
})();

好的写法:
var arr = ...;
var globalVar = 0;
(function () {
var i, l, localVar;
l = arr.length;
localVar = globalVar;
for (i = 0; i < l; i++) {
localVar++;
}
globalVar = localVar;
})();


2.减少符号查寻(2):原型链
-访问主对象上的成员的速度比访问原型链上的成员的速度快25%
-原型链越长查寻越慢
function A () {}
A.prototype.prop1 = ...;

function B () {
this.prop2 = ...;
}

B.prototype = new A();
var b = new B();//(译者:prop2为b的主对象成员,而prop1是原型链上的成员)

3.优化对象实例化
-如果你需要创建很多对象,可以考虑添加成员到原型中,而不添加到单个对象的构造器中。
-这样会减少内存的消耗
-然而会拖慢查寻查寻对象成员的速度

4.不要使用eval
-传字符串到eval中,需要编译和解释,相当的慢!
-完全不要传一个字符串到setTimeout和setInterval中。可以使用匿名函数代替。
setTimeout(function () {
// Code to execute on a timeout
}, 50);
-完全不要eval做为方法的构造器。

5.优化字符串连接
-在IE(JScript)中,连接两个字符串会导致一个新的字符串被重新分配资源,同时两个原字符串被复制:
var s = "xxx" + "yyy";
s += "zzz";
-因此在IE中,添加字符串到数组中然后再用Array.join连接比直接用+连接快很多(不要用在简单的连接中)
-其他Javascript引擎(WebKit、SpiderMonkey)已经对字符串连接做了优化
-使用YUI Compressor!

6.优化正则表达式
-尽量不要用RegExp构造,除非你的正则表达式需要实时创建。
-使用test方法测试一个pattern(exec方法会有小的性能问题)
-使用非捕获组(?:)
-保持pattern的简单

7.缓存
-在下面情况下应用缓存是合理的:
* 更低成本的获取一个值
* 值会被经常读取
* 值不经常改变
-会增加内存消耗(权衡)
-Memoization:
Module Pattern:

Store value in function object:


function fn () {
if (!fn.b) {
fn.v = ...;
fn.b = true;
}
return fn.v;
}

Lazy function definition:
var fn = function () {
var v = ...;
return (fn = function () {
return v;
})();
};

8.如何控制长时间运行处理的Javascript
-在Javascrit的长时间运行处理过程中,整个浏览器会被冻结
-因此为了维持好的用户体验,确保Javascript一个线程在约300兆秒内完成
-你可以通过用setTimeout将长运行处理拆成的更小处理单元串起来执行
-更多见http://www.julienlecomte.net/blog/2007/10/28/
-例子http://www.julienlecomte.net/blogfiles/javascript/long-running-js-process.html
function doSomething (callbackFn) {
// Initialize a few things here...
(function () {
// Do a little bit of work here...
if (termination condition) {
// We are done
callbackFn();
} else {
// Process next chunk
setTimeout(arguments.callee, 0);
}
})();
}

9.综合技巧
-简单的操作符往往比相应的方法要快
c = Math.min(a, b);
c = a < b ? a : b;//更快

myArray.push(value);
myArray[myArray.length] = value;//比上面快
myArray[idx++] = value;//比上面快

-避免使用try...catch在影响性能的部分:
不好的写法:
var i;
for (i = 0; i < 100000; i++) {
try {
...
} catch (e) {
...
}
}
好的写法:
var i;
try {
for (i = 0; i < 100000; i++) {
...
}
} catch (e) {
...
}
-If possible, avoid for...in in performance-critical sections
-无论何时分支条件都不改变的情况下,分支应该在外面,不要在里面:
不好的写法:
function fn () {
if (...) {
...
} else {
...
}
}

好的写法:
var fn;
if (...) {
fn = function () {...};
} else {
fn = function () {...};
}


第4部分 高性能的动态HTML

1.文档树的修改:使用innerHTML
注意事项http://www.julienlecomte.net/blog/2007/12/38

2.文档树的修改:使用cloneNode
注意:expando属性或附加的事件会丢失

3.文档树的修改:使用DocumentFragment
-DocumentFragment(DOM Level 1 Core)是一个轻量级的文档对象
var i, j, el, table, tbody, row, cell, docFragment;
docFragment = document.createDocumentFragment();
el = document.createElement("div");
docFragment.appendChild(el);
table = document.createElement("table");
el.appendChild(table);
tbody = document.createElement("tbody");
table.appendChild(tbody);
for (i = 0; i < 1000; i++) {
...
}
document.body.appendChild(docFragment);
-它仅仅支持常规DOM方法和属性的子集
-IE实现DocumentFragment不服从W3C规范

4.限制事件柄的个数
-附加事件到上百个元素上的成本很高
-多个事件柄会增加潜在的内存漏洞
-解决方案:使用事件委托机制,一种依靠事件冒泡的机制

5.限制回流(Reflow)


第5部分 高性能的布局和CSS

综合技巧
-使用CSS Sprites
-避免使用Javascript布局
-避免使用IE表达式
-避免使用IE滤镜(或尽可能少用)
-优化Table布局
-优化CSS选择器http://developer.mozilla.org/en/docs/Writing_Efficient_CSS


第6部分 高性能的Ajax

1.综合技巧
-完全不要使用同步的XMLHttpRequest。参见http://yuiblog.com/blog/2006/04/04/synchronous-v-asynchronous
-编程处理网络超时
-解决方案:使用YUI Connection Manager
var callback = {
success: function () { },
failure: function () { },
timeout: 5000
};
YAHOO.util.Connect.asyncRequest("GET", url, callback);

2.提升可以感觉到的网络延迟体验
-如果数据在提交到服务器端之前经过本地校验,通常请求的成功率达99.9%
-因此,为了优化用户体验,我们可以采用下面的Pattern:
* 当请求发出时要更新UI
* Lock the UI/data structures with the finest possible granularity.
* 让用户知道发生了什么事
* 让用户知道为什么UI被锁定
* 当成功返回结果后要及时解除锁定
* 要用优雅的方式处理错误

3.综合技巧
-知道并发HTTP/1.1连接的最大数量
-如果后端支持,支持多元的Ajax请求
-Piggyback unsollicited notifications in a response to an Ajax request.
-用JSON代替XML做为数据交换格式
-推送,不要轮询。使用COMET向浏览器发送实时的通知
-考虑使用本地存储器缓存数据。
* IE的userData
* Flash本地存储
* DOM:Storage(WHATWG持久存储API, 已在Firefox2中实现)
* Google Gears
* 其它


第7部分 性能工具

-YSlow? http://developer.yahoo.com/yslow
-Task Manager
-IE Leak Detector a.k.a Drip [ http://www.outofhanwell.com/ieleak/ ]
-Stopwatch profiling
* AjaxView [ http://research.microsoft.com/projects/ajaxview/ ]
* JsLex [ http://rockstarapps.com/pmwiki/pmwiki.php?n=JsLex.JsLex ]
* YUI profiler [ http://developer.yahoo.com/yui/profiler/ ]
-Venkman or Firebug Profiler [ http://www.getfirebug.com/ ]

(原文:http://yuiblog.com/blog/2007/12/20/video-lecomte/ )

相关文章推荐

编写高性能的JavaScript-Ajax数据传输之MXHR

动态载入脚本 这个技术的特点克服了XHR最大的缺点:跨域访问。使用如下: var scriptElement = document.createElement('script'); ...
  • xxfigo
  • xxfigo
  • 2012年04月24日 23:09
  • 1417

开发那点事系列四 - 如何构建高效Ajax应用

如何提高Ajax应用的质量和性能,概括来讲,该过程主要包含以下几个步骤:      1.JavaScript代码的潜在错误和代码风格检查。通过集成JSLint可以找到代码中潜在的问题。  ...

构建高性能J2EE应用的10个技巧

  • 2013年07月24日 18:08
  • 18KB
  • 下载

分解和合并:Java 也擅长轻松的并行编程! 作者:Julien Ponge

文中的程序我也测试过了,  注意下面的红字部分,在测试的时候我们需要保护测试环境尽可能等价,要么 分成2次测试  一次输出串行的时间  一次输出并行的时间,如果想在一个方法中比较,那么两者的先后顺序就...

开发高性能的ASP_NET应用

  • 2009年01月21日 09:26
  • 776KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:高性能的Ajax应用-Julien Lecomte
举报原因:
原因补充:

(最多只允许输入30个字)