是什么让你的ExtJS应用程序运行缓慢?
原文链接:http://iamtotti.com/blog/2011/05/what-makes-your-extjs-application-run-so-slow/
本文说的“缓慢”,是只运行时的缓慢,而不是只加载资源的时间。
在过去的一年半以来,我一直与Robert Bosch在Bosch软件创新公司工作,在那里我们的前端技术堆栈非常依赖ExtJS。我有机会开发Visual Rules Web Modeler机器协助开发其它几个基于ExtJS的应用,因此,我积累了不少与ExtJS应用常见的性能问题有关的经验。
在这篇文章中,我将与你们分享导致ExtJS应用运行缓慢的瓶颈问题,并指出ExtJS开发者最容易犯的错误。
本文提及的ExtJS是指版本3.3.x及以下版本的ExtJS。
1、过度的Ext.Panel定义
在我看来,最常用的ExtJS组件是Ext.Panel。在ExtJS里定义一个面板太简单了,因而很多开发人员很容易就会过度的定义它。下面是一个典型的嵌套了子面板的面板定义:
1 | var panel = new Ext.Panel({ // Level-1 |
2 | title: 'Multi Column, Nested Layouts and Anchoring', |
3 | bodyStyle:'padding:5px 5px 0', |
4 | width: 600, |
5 | items: [{ // Level-2 |
6 | layout:'column', |
7 | items:[{ // Level-3 |
8 | columnWidth:.5, |
9 | layout: 'vbox', |
10 | items: [{ // Level-4 |
11 | html: 'This is some text' |
12 | }, { |
13 | html: 'This is another text' |
14 | }] |
15 | },{ |
16 | columnWidth:.5, |
17 | layout: 'form', |
18 | items: [{ |
19 | xtype:'textfield', |
20 | fieldLabel: 'Last Name', |
21 | name: 'last', |
22 | anchor:'95%' |
23 | },{ |
24 | xtype:'textfield', |
25 | fieldLabel: 'Email', |
26 | name: 'email', |
27 | vtype:'email', |
28 | anchor:'95%' |
29 | }] |
30 | }] |
31 | }] |
32 | }); |
这定义有问题吗?没有?这里的主要问题是嵌套了4层面板,而实际上,只需要2层就可以工作了。
●这是一个过渡定义的例子,它导致了多层深度的嵌套的HTMLElement创建,以致严重影响了初始化时间、渲染时间和组件的运行时间。
●我见过很多ExtJS开发人员习惯定义嵌套面板,因为它这样可以方便在面板里加入自定义的样式、文本和图片等等,或者有时仅仅是因为显示需要,在里面添加其它的面板,
●经验法则是:用尽可能少的面板和尽可能的减少面板(组件)的嵌套。
要做到这一点,在定义一个复杂的组件时,必须明智地使用Ext的布局及其样式,
2、尽可能延迟HTMLElement的创建
DOM操作(读/写)的开销一向是昂贵的,尤其在IE6,读取DOM总会引起回滚。
因此,经验法则是:尽可能延迟HTMLElement的创建。以下是实现方式:
●组件Lazy初始化,这在xtype里可实现。
●尝试在渲染后(afterrender)后再执行昂贵的操作。
●避免在组件的构造函数或initComponent方法中对其它组件进行不必要的实例化或渲染。
例子1:1个简单的例子就是在按钮第一次渲染时,不创建Ext.Tooltio或在一个隐藏的DOM节点渲染它。tooltip通常会在用户第一次将鼠标移动到按钮上面时进行渲染。如果tooltip在按钮之后显示,用户就不必将鼠标移动到按钮上了。其实这是一种浪费,永远不要做这样的事,使用tooltip只会增加性能问题。
示例2:另一个例子是粗心的使用renderTo:
1 | var window = new Ext.Window({ |
2 | renderTo: document.body, |
3 | title: 'The Untitled' |
4 | }); |
5 | |
6 | window.show(); // 窗口将会在这之前渲染 |
上述定义,窗口将会立即渲染和隐藏在body标记内。在大多数情况下,窗口根本不需要使用renderTo,因为它会在第一次显示时进行渲染:
1 | var window = new Ext.Window({ |
2 | title: 'The Untitled' |
3 | }); |
4 | |
5 | window.show(); // 窗口会在这时候进行渲染 |
3、尽可能使用委托模式
我不会在这里深入挖掘委托模式的细节,但会在ExtJS语法基础上重组它。
示例:一个委托模式的示例是工具条有10个按钮,而你希望在用户将鼠标移动到按钮上面时,为每个按钮委派一个Ext.Tooltip,而且每个Ext.Tooltip都显示不同的文本。
如果你创建10个Ext.Tooltip并委派给10个按钮,那么它不是一个优化的解决方案。你只需要创建一个Ext.Tooltip并委派给10个按钮的父元素,也就是工具条。
当用户将鼠标移动到工具条上方时,你可以显示相同的Ext.Tooltip,但其文本可根据目标元素(实际上就是按钮)而显示不同的文本(越多getTarget方法可了解如何获取目标元素)。
使用这个技术,只需要创建1个Ext.Tooltip,而且只需要在工具条绑定一个监听事件。
这可节省内存使用,而且在你的应用运行时实现了相同的效果。
你可以在这里找到示例中Ext.Tooltip的delegate属性信息。
4、组件销毁——如何正确销毁
在我协助提供性能期间,我发现ExtJS应用缓慢的一个主要瓶颈就是组件的销毁。这里所说的组件销毁是指不再使用的组件,我们应该清理:
●DOM中的HTMLElement。
●移除所有监听事件以避免内存泄漏。
●通过递归方式销毁所有子组件。
以上这些可通过组件的destory方法来处理。有些情况下你需要在运行时调用destroy方法,因为将没有用的组件遗留在DOM中会导致严重的低性能。
示例1:如果你在一个面板内创建了一个弹出菜单,记得重写面板的destroy方法,在里面添加销毁弹出菜单的代码。这样,当面板被销毁时,弹出菜单也会被销毁。
1 | Your.Component.Klass = Ext.extend(Ext.Component, { |
2 | initComponent: function(){ |
3 | // Initialize your custom stuff |
4 | this.contextMenu = new Ext.menu.Menu({ |
5 | renderTo: document.body |
6 | // .. |
7 | }); |
8 | }, |
9 | |
10 | destroy: function(){ |
11 | // Destroy your custom stuff |
12 | this.contextMenu.destroy(); |
13 | this.contextMenu = null; |
14 | |
15 | // Destroy the component |
16 | Your.Component.Klass.superclass.destroy.call(this); |
17 | } |
18 | }); |
示例2:大家都会犯的错误就是错误定义窗口的closeAction配置项。
如果配置closeAction为hide,那么当用户单击关闭按钮关闭窗口时,窗口将变成不可见。然而,有时候,窗口在整个运行期间,都不会再显示第二次。因而,你必须确保窗口是需要隐藏或显示的,不然就配置closeAction为close,以便在窗口被关闭时执行destroy方法以销毁窗口。
1 | var window = new Ext.Window({ |
2 | closeAction: 'hide', |
3 | title: 'The Untitled' |
4 | }); |
5 | |
6 | window.show(); // render and display the window |
7 | window.hide(); // the window is not destroyed but only hidden in the DOM. |
我希望本文能给大家一些线索以提高ExtJS应用的性能。如果你有其它与ExtJS应用性能有关的问题和经验,可以随时在这里分享。
干杯,
作者:Totti
是什么让你的ExtJS应用程序运行缓慢?相关推荐
- 移动应用程序和网页应用程序_您的移动应用程序运行缓慢的主要原因以及如何修复它...
移动应用程序和网页应用程序 by Rajput Mehul 通过拉杰普特·梅胡尔(Rajput Mehul) 您的移动应用程序运行缓慢的主要原因以及如何修复它 (Top Reasons Why You ...
- 阿里Java诊断工具 arthas - 监测线上系统的运行信息、排查程序运行缓慢等问题
一.arthas 上篇文章我们讲解了使用arthas在线上环境排查定位内存占用过大.cpu使用率过高等问题,本篇文章继续使用arthas监测线上系统的运行信息,以及排查程序运行缓慢等问题. 下面是上篇 ...
- php太卡,ps卡顿怎么办 程序运行缓慢的解决方法
photoshop作为我们常用的绘图工具,但是有时候会越来越慢,那么ps卡顿怎么办?下面小编带来程序运行缓慢的解决方法,希望对大家有所帮助. 程序运行缓慢的解决方法: 首先是暂存盘的选择,安装后第一次 ...
- Linux 交换空间优化(swap 优化)(积极使用交换空间占比,可能会使程序运行缓慢!)
linux 2.6+的核心会使用硬盘的一部分做为SWAP分区,用来进行进程调度–进程是正在运行的程序–把当前不用的进程调成'等待(standby)',甚至'睡眠(sleep)',一旦要用,再调成'活动 ...
- java程序运行缓慢原因_Java 很普通的代码执行很慢
大家好,我们生产系统上面现在有一个接口,这个接口里面的代码有的时候运行很慢,后来我把代码分成了好几段,每段代码前后都加了开始时间和结束时间.今天下午 2020/4/7 14:48:00 的时候,运维找 ...
- java游戏开发--连连看-让程序运行更稳定、更高效
之六)优化:让程序运行更稳定.更高效 改善游戏的合理性 到目前为止,我们的游戏基本上算是完成了,为了使程序更合理,我们还需要将整个程序从头再理一遍,看看有没有改进的地方. 首先,在变量的使用上,由于很 ...
- Linux系统程序运行时加载动态库路径顺序
程序运行时加载动态库路径顺序(Linux) 在linux系统中,如果程序需要加载动态库,它会按照一定的顺序(优先级)去查找: 链接时路径(Link-time path)和运行时路径(Run-time ...
- 从hello world 说程序运行机制
http://www.cnblogs.com/yanlingyin/archive/2012/03/05/2379199.html 开篇 学习任何一门编程语言,都会从hello world 开始.对于 ...
- 查询在应用程序运行得很慢, 但在SSMS运行得很快的原因探究
原文:查询在应用程序运行得很慢, 但在SSMS运行得很快的原因探究 查询在应用程序运行得很慢, 但在SSMS运行得很快的原因探究 -理解性能疑点 1 引言 内容来自http://www.so ...
最新文章
- 实例解说.Net构架下的加密编程
- 在网易,我是怎样做项目管理的?
- springboot aop使用_Spring Boot 的自动配置,是如何实现的?
- Linux下的用户和组
- RBF非线性滤波的Matlab,基于RBF神经网络的非线性滤波器的研究
- 001_深度剖析什么是 SLI、SLO和SLA?
- 分区表的误区:性能提升
- HighCharts:plotLines基准线与数据相差过大不显示
- 深入研究ActivityMQ
- lbochs模拟器最新版_手机模拟器电脑模拟器-bochs模拟器安卓版下载 v2.6.8-都去下载...
- 搜苹果ipad版_苹果iOS低版本软件最快下载教程
- c语言许多名字随机抽取名字,怎么用ppt实现一个随机抽取名字的功能
- python pyhook_pyhook的简单使用
- 查看linux下eclipse进程,Linux环境安装Eclipse工具开发
- 读《男子为让孩子成为北京人执意找京籍女结婚(图)》有感——致北漂的XDJM
- app性能测试怎么做
- 区块链如何改变出版商在学术传播中的角色
- word-search
- 十道必问的软件测试面试题(含答案解析)
- linux下搜狗安装目录,搜狗输入法Linux版配置文件详解
热门文章
- Vue中常见的性能优化
- wrapper php,PHP流Streams、包装器wrapper概念与用法实例详解
- spark kafka java api_java实现spark streaming与kafka集成进行流式计算
- zimbra mysql管理_zimbra 命令行管理
- 20220104:力扣第274场周赛(下)
- mysql怎么用sb文件_初识mysql数据库
- oracle字符串处理substr、dbms_lob.substr、case when
- ARM中的---汇编指令
- 构建基于流程的多维度企业管理体系
- 前阿里P10大神AI创业,主打决策智能,从《星际争霸II》开始