本文說的「緩慢」,是只執行時 的緩慢,而不是只載入資源的時間。
在過去的一年半以來,我一直與robert bosch在bosch軟體創新公司工作,在那裡我們的前端技術堆疊非常依賴extjs。我有機會開發visual rules web modeler機器協助開發其它幾個基於extjs的應用,因此,我積累了不少與extjs應用常見的效能問題有關的經驗。
在這篇文章中,我將與你們分享導致extjs應用執行緩慢的瓶頸問題,並指出extjs開發者最容易犯的錯誤。
本文提及的extjs是指版本3.3.x及以下版本的extjs。
1、過度的ext.panel定義
在我看來,最常用的extjs元件是ext.panel。在extjs裡定義乙個面板太簡單了,因而很多開發人員很容易就會過度的定義它。下面是乙個典型的巢狀了子面板的面板定義:
view source
print?
01.
var
panel =
new
ext . panel ( , ]
15.
} , , ]
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:
view source
print?
1.
var
window =
new
ext . window ( ) ;
5.
6.
window . show ( ) ;
// 視窗將會在這之前渲染
上述定義,視窗將會立即渲染和隱藏在body標記內。在大多數情況下,視窗根本不需要使用renderto,因為它會在第一次顯示時進行渲染:
view source
print?
1.
var
window =
new
ext . window ( ) ;
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方法移除不使用的元件,會導致嚴重的效能下降。
示例1:如果你在乙個面板內建立了乙個彈出選單,記得重寫面板的destroy方法,在裡面新增銷毀彈出選單的**。這樣,當面板被銷毀時,彈出選單也會被銷毀。
view source
print?
01.
your . component . klass = ext . extend ( ext . component , ) ;
08.
} ,
09.
10.
destroy :
function
( )
18.
} ) ;
示例2:大家都會犯的錯誤就是錯誤定義視窗的closeaction配置項。
如果配置closeaction為hide,那麼當使用者單擊關閉按鈕關閉視窗時,視窗將變成不可見。然而,有時候,視窗在整個執行期間,都不會再顯示第二次。因而,你必須確保視窗是需要隱藏或顯示的,不然就配置closeaction為close,以便在視窗被關閉時執行destroy方法以銷毀視窗。
view source
print?
1.
var
window =
new
ext . window ( ) ;
5.
6.
window . show ( ) ;
// render and display the window
7.
window . hide ( ) ;
// the window is not destroyed but only hidden in the dom.
是什麼讓你的ExtJS應用程式執行緩慢?
本文說的 緩慢 是只執行時的緩慢,而不是只載入資源的時間。在過去的一年半以來,我一直與robert bosch在bosch軟體創新公司工作,在那裡我們的前端技術堆疊非常依賴extjs。我有機會開發visual rules web modeler機器協助開發其它幾個基於extjs的應用,因此,我積累了...
是什麼讓你的ExtJS應用程式執行緩慢?
本文說的 緩慢 是只執行時的緩慢,而不是只載入資源的時間。在過去的一年半以來,我一直與robert bosch在bosch軟體創新公司工作,在那裡我們的前端技術堆疊非常依賴extjs。我有機會開發visual rules web modeler機器協助開發其它幾個基於extjs的應用,因此,我積累了...
是什麼讓你的ExtJS應用程式執行緩慢?
本文說的 緩慢 是只執行時的緩慢,而不是只載入資源的時間。在過去的一年半以來,我一直與robert bosch在bosch軟體創新公司工作,在那裡我們的前端技術堆疊非常依賴extjs。我有機會開發visual rules web modeler機器協助開發其它幾個基於extjs的應用,因此,我積累了...