zoukankan      html  css  js  c++  java
  • 是什么让你的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里定义一个面板太简单了,因而很多开发人员很容易就会过度的定义它。下面是一个典型的嵌套了子面板的面板定义:

    var panel = new Ext.Panel({         // Level-1
         title: 'Multi Column, Nested Layouts and Anchoring',
         bodyStyle:'padding:5px 5px 0',
         width: 600,
         items: [{                   // Level-2
            layout:'column',
            items:[{                // Level-3
                   columnWidth:.5,
                   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:

    var window = new Ext.Window({
         renderTo: document.body,
         title: 'The Untitled'
    });
     
    window.show(); // 窗口将会在这之前渲染

          上述定义,窗口将会立即渲染和隐藏在body标记内。在大多数情况下,窗口根本不需要使用renderTo,因为它会在第一次显示时进行渲染:

    var window = new Ext.Window({
           title: 'The Untitled'
    });
     
    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方法,在里面添加销毁弹出菜单的代码。这样,当面板被销毁时,弹出菜单也会被销毁。

    Your.Component.Klass = Ext.extend(Ext.Component, {
    initComponent: function(){
         // Initialize your custom stuff
         this.contextMenu = new Ext.menu.Menu({
               renderTo: document.body
               // ..
          });
    },
     
    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方法以销毁窗口。

    var window = new Ext.Window({
       closeAction: 'hide',
       title: 'The Untitled'
    });
     
    window.show(); // render and display the window
    window.hide(); // the window is not destroyed but only hidden in the DOM.

          我希望本文能给大家一些线索以提高ExtJS应用的性能。如果你有其它与ExtJS应用性能有关的问题和经验,可以随时在这里分享。大笑

             干杯,

            作者:Totti

  • 相关阅读:
    【转】关于char * 与 char[]
    网页打印js代码
    无法用排他锁锁定该数据库,以执行该操作。 (Microsoft SQL Server,错误: 5030)
    CKEditor使用笔记
    FormView作为单独编辑页笔记
    用WindowsMediaPlayer控件写个WinForm播放器
    ListView搭配DataPager控件实现分页笔记
    如何禁用ViewState
    C#获取本机IP搜集整理7种方法
    ListView高效率分页笔记
  • 原文地址:https://www.cnblogs.com/muyuge/p/6333795.html
Copyright © 2011-2022 走看看