原文标题: Sencha Con 2013: Ext JS Performance tips
原文地址: [http://edspencer.net/2013/07/19/sencha-con-2013-ext-js-performance-tips/]
在和 Jacky 谈话之前,我还没计划发布一个独立的文章来分享在 extjs 编程的小建议,但这个内容实在非常好,并且我后来也记下了很多根据他原始空间中的笔记。为了让我们我自己从刚开始时学习遇到阻碍,我想给分析下 extjs 优化方面一些建议会给大家带来很多帮助。
extjs 随着每一次发布新版本,变得越来越灵活强大了。你现在可以通过它来做很多之前必须由你亲自来做的事情,但是,在使用 extjs 时需要考虑效率的一个问题。在很多情况下,这些低效率是由于不恰当使用框架时所造成的,而不是框架本身的问题。
有很多方式,可以用来加速你正不满意应用程序的效率,Nige在一个美丽的早晨,向我们介绍了这些方法。这也是这次我记下来的内容。
Nige 总结了3个最经常出现的,使得程序效率低下的原因,我们接下来将一个一个的进行介绍
1. 网络因素
2. javascript执行效果
3. 层的活动性
网络很差的情况下,会造成非常不友好的用户体验——使得应用程序启动时呈现一段空白的屏幕
使用 sencha 命令行编译工具来编译项目,将得到一个单一、被压缩的文件,将会得到这样的好效果:4810ms vs 352ms = 动态加载 vs 编译后
1. 避免减慢 javascript 引擎的操作(他是带着苦笑说的)
2. 优化重复的代码——例如,循环体内应该是非常紧凑的代码,缓冲变量尽量在循环体外被定义;不要在将对象附加到DOM元素时,进行其他的任何操作
3. 减少函数调用次数
4. 延迟加载实例化的对象
5. 使用网页分析工具(在extjs sdk 的示例文件夹中)来规范地分析你的应用程序
在启动 chrome 浏览器时,打开 –enable-benchmarking 标准属性,来得到在浏览器中执行时精确的运行时间信息
在增加或移除很多记录时,需要暂停 store 的事件。否则的话,我们将会在每一条记录被修改时,在全部层中传递修改的事件。
grid.store.suspendEvents();
//do lots of updating
grid.store.resumeEvents();
grid.view.refresh()
* 树控件中重复的东西(他们与表格属于同一类的)
尽可能地合并多个层。如果你正在一个简单的操作中添加或删除一串的组件,可以像这样来做:
Ext.suspendLayouts();
//do a bunch of UI updates
Ext.resumeLayouts(true);
容器类(Container)中的 add 方法接受数据项为数组的参数,这种方式的效率比通过迭代来一个个添加的方式快很多。尽可能低避免层之间的相互约束——在盒子层中,设置对齐方式为:‘stretchmax’是非常低效的。因为它不得不做在多个层中运行。尽快能地避免设置最小高度、最大高度、最小宽度、最大宽度等。
* 在启动时
如果可能的话,尽可能在静态代码中完成数据初始化的工作——避免在初始需要数据的层中设置通过 ajax 请求来获取数据
不要一次发送多个 ajax 请求,并且使用空闲的事件名(idle)在响应数据中构建层对象。
* 使用空闲事件
与动态排队的方式非常相似
Ext.globalEvents.on(‘idle’, myFunction) – 将会在很耗时的层操作/重绘等完成后,被调用
使用空闲事件监听通常比 setTimeout(myFunction, 1) 操作更好,因为它在同等的重绘循环中是一个异步操作。这 setTimeout 过程意味着重绘发生了,然后你的代码被调用。如果你代码自身就要求一次重绘,那么意味着你将在 setTimeOut 方式中有两次重绘,而在空闲事件方式中,只会有一次重绘工作
* 减少层的深度
最大的问题——过多的嵌套。通常大家很喜欢对表格做这样的操作:
{
xtype: 'tabpanel',
items: [
{
title: 'Results',
items: {
xtype: 'grid'
}
}
]
}
更好的方式应该是这样的:
{
xtype: 'tabpanel',
items: {
title: 'Results',
xtype: 'grid'
}
}
这是非常重要的,因为多余的组件将会消耗CPU和内存。现在每一件事都是一个组件,不管是面板的标题、小图标等等。比你预计中构建了更多的组件。越强大可扩展性,久越容易造成滥用。
延迟实例化操作,新的插件可以在以下链接中找到。 [https://gist.github.com/ExtAnimal/c93148f5194f2a232464]
{
xtype: 'tabpanel',
ptype: 'lazyitems',
items: {
title: 'Results',
xtype: 'grid'
}
}
* Overall impact
在实际操作中,通过 sencha 客户贡献的庞大示例可以得到如下结论:
差的代码: 5187ms (IE8)
好的代码: 1813ms (IE8)
同样的示例代码,在Chrome浏览器中,差的代码与好的代码之间的时间比是:1300ms vs 550ms
这现在只是理论上的探讨,你将在实际项目中看到它们的效果。这仅仅是课程内容的一小部分,而且是在一个经验不丰富的开发者我的口中(the horse's mouth 真有意思,不知道翻译得对不对)说出来的。Nige在分享这些建议时做得非常棒,并且提醒我们优化操作是开发者和框架共同的责任——这框架正随着时间发展而变得越来越快,但我们这些开发者也应该做好自己的事情,来确保使用这个框架时,仍然能继续保持高的效率。
从这篇文章中,学习到了一些新的词,动态排队(AnimationQueue)、空闲事件(idle event),我想这些技术应该是非常好的方向,是需要掌握的。
我们总说项目时间太紧,因此而放弃对代码的效率的提升,这是非常不推荐的,只要利用好了这些工具,提高了代码的效率,才能让我们更加自信地面对客户朝令夕改的需求变更,才能让我们这些程序员提高自身的竞争力!