優化基於ExtJS 4.1的應用

雖然Sencha在Ext JS 4.1提高了性能,但基於Ext JS的應用性能優化仍然是奮鬥目標。要優化應用性能,通常需要根據Ext JS的增強優勢對修改代碼。本文將介紹如何實現優化

E文好的朋友,可以到http://www.sencha.com/blog/optimizing-ext-js-4-1-based-applications查看原文。

雖然Sencha在Ext JS 4.1提高了性能,但基於Ext JS的應用性能優化仍然是奮鬥目標。要優化應用性能,通常需要根據Ext JS的增強優勢對修改代碼。

本文將介紹如何實現優化,還將介紹一個用於Ext JS 4.1的新的性能測量工具——頁面分析器。其主要功能是改善應用的性能。通過它,就可以定出測量指標兵測量它,從而找出代碼中的瓶頸,兵採取正確的步驟消除瓶頸。頁面分析可以做到這一點。最後,還將介紹Grid的優化,並介紹另一個新的用於評估Grid性能的Ext JS工具——Infinite Grid Tuner。

正如我們爲Ext JS開發人員工作一樣,我們注意到幾個共同的趨勢,在編寫應用程序時要提供性能調整的辦法。雖然我們不能一一列舉拖垮應用程序的每個編碼技術,但通過以下介紹的方法,高開發人員就可在使用框架時提高應用程序的性能。

檢查事件監聽

在應用程序中如何使用事件監聽是一個提供性能的一個關鍵。例如,想在Store第一次加載數據時觸發load事件,如果不注意,就會造成Store每次加載數據時都會觸發load事件。這時候,在Store第一次加載數據觸發load事件後關閉它,將會提升應用程序的整體性能。方法就是在監聽中添加“single:true”:

  1. listeners: {

  2. load: onFirstLoadData,

  3. single: true

  4. }

另外一個經常忽略的是afterrender事件,它會在所有DOM元素都渲染後觸發。渲染後修改元素會引起迴流(reflows),從而降低應用性能。相反,使用beforerender事件,在渲染前調整元素的樣式,可讓元素在渲染時就是正確的樣式。有時候,一些代碼必須在渲染後,元素的大小被確定後才能運行。這時候,在Ext JS 4.1,可以考慮使用其提供的一個新事件——boxready,它會在組件大小確定後觸發。

移除doLayout和doComponentLayout的調用

簡而言之,就是儘量移除這些昂貴的調用。在舊版本Ext JS(4.0之前),doLayout會讓框架在組件或容器繼續前進時,重新計算其佈局。即使在Ext JS 4.0,有時候,也需要在直接更新DOM後或解決某些缺陷時調用它。

在Ext JS 4.1,佈局的觸發有點不同,因而,代碼基本不需要調用doLayout或doComponentLayout。如果你的應用事實上需要這些調用來解決錯誤,那麼請提交一個bug報告,一把我們能修復它。

唯一非錯誤時,需要調用doLayout或doComponentLayout,是在應用代碼直接修改DOM的時候。原因是框架不知道這樣的變化,因而需要調用它們更新受影響的佈局。

減少容器嵌套

我們經常看到過多嵌套容器的應用,例如,一個容器內只有一個容器,而這個容器內有多個組件。這時候,可以取消外層容器,只使用一個容器完成同樣的工作。很重要的一點,必須記住,每個容器的初始化、渲染和佈局都需要花費時間,因而,必須排除這些不必要的嵌套容器,這樣,應用將運行得更快。類似的代碼如下(id屬性在實際上很少見到,添加在這裏是爲了標記這裏有兩個容器):

  1. {

  2. id: 'container1',

  3. items: [{

  4. id: 'container2',

  5. items: [{

  6. id: 'component3'

  7. }]

  8. }]

  9. }

如果可能,上面代碼可減少爲一個容器:

  1. {

  2. id: 'container1',

  3. items: [{

  4. id: 'component3'

  5. }]

  6. }

使用容器替換面板

請記住,Ext JS面板比容器功能強大,但也是很昂貴的。因而,最好指定“xtype: 'container'”,以避免應用使用默認的面板,如下所示:

(譯者注:面板包含標題、工具欄等很多部件,因而其實例化時要創建很多部件的實例,並做很多佈局運算,而容器就是一個簡單的div,因而在非必要情況下使用容器,確實會大幅改善應用的性能,這個一定要切記)

  1. {

  2. xtype: 'container', // defaultType is 'panel'

  3. items: [ ... ]

  4. }

減少邊框佈局(borderLayout)嵌套

在Ext JS4.1,很多情況下,不再需要使用邊框佈局嵌套。移除嵌套可以減少初始化、渲染和佈局組件的時間。在ExtJS之前的版本很多情況下都需要嵌套,例如,在同一區域內有兩個或兩個以上相同的區域。在Center區域上有2個North區域的時候,你必須嵌套邊框佈局。現在,使用一個邊框佈局就可以實現兩個North區域。

在Ext JS4.1,區域可以根據需要動態添加,任何添加的區域可在前端顯示並在不需要的時候隱藏它們。還可以通過weight屬性定義區域的優先權,例如,可以定義West區域的優先權在North區域之前。這些變化意味着不再需要嵌套邊框buutons,從而提高使用該佈局的組件的渲染速度。

(譯者注:該功能的改變非常方便,現在設計佈局比之前版本的輕鬆多了)

減少DOM的讀取和寫入

在Ext JS4.1,我們已經儘可能的減少了佈局對DOM的讀取和寫入。同樣,在你的代碼也需要這樣做。DOM在讀取自身時會降低應用速度,尤其是在混合了DOM寫入操作時的開銷相當高,而且這樣結合會引起迴流。嘗試使用beforerender來維護樣式,這樣可以在渲染時修改組件,而不是在渲染後。避免使用setStyle、addCls、removeCls以及其它直接修改DOM元素的語句,這些語句都會引起寫入操作。作爲一般規則,爲了獲得更好的性能,維護DOM時需要寫入時,多嘗試使用批量讀取和寫入。

使用Ext.suspendLayouts和Ext.resumeLayouts消除額外的佈局操作

Ext JS 4.1提供了Ext.suspendLayouts和Ext.resumeLayouts兩個新方法來協調多個組件和容器的更新。例如,要迅速增加兩個組件到兩個連續容器,會導致多個佈局和渲染操作被執行。如果在添加這些組件之前調用Ext.suspendLayouts方法,將不再單獨執行個別組件的佈局操作。添加完成後,調用Ext.resumeLayouts方法,框架將只執行一次渲染和佈局操作。

謹記,不單添加組件會觸發容器的佈局操作,組件的其它操作或改變也會觸發容器的佈局操作。重要的是針對在應用中的性能問題進行具體情況具體分析,以確保沒有多餘的佈局操作被執行。

  1. {

  2. Ext.suspendLayouts();

  3. // batch of updates

  4. Ext.resumeLayouts(true);

  5. }

Ext JS頁面分析器介紹

Ext JS 4.1帶有一個新工具,可用來查找和衡量應用程序的性能問題。通過它,可快速檢測代碼的修改對性能的影響。頁面分析器會在加載Ext JS 4.1頁面時與診斷工具掛鉤。頁面分析器包含了許多實驗性功能,本文將介紹其最有用的,用於優化應用性能的佈局選項卡。

你可以在Ext JS 4.1 SDK包的示例文件夾(Examples)下找到該工具:

  1. ./examples/page-analyzer/page-analyzer.html

複製整個“page-analyzer”文件夾到要分析的應用主機上,因爲瀏覽器安全問題,頁面分析器必須與分析頁面在同一服務器上進行通訊,而且要確保頁面分析器的版本與Ext JS的版本號匹配。如果使用不同的版本,它會罷工。

注意,該工具是首次發佈,還處於發展中,因而,請通過Ext JS論壇將工具的使用情況反饋給我們。

以下是使用頁面分析器的步驟:

1、打開瀏覽器兵輸入頁面分析器的地址。

2、打開後,在分析器中輸入測試頁面的地址。

3、頁面將在iframe中加載,這就是爲什麼分析器必須與應用在同一服務器的原因。打開頁面後的分析器如下圖所示:

頁面分析器

單擊佈局選項卡,將看到如下圖所示的佈局運行情況。

頁面分析器

你可以在同一個組件中找到多個佈局操作,然後查看你的代碼,看看是否可以通過減少佈局操作來提高性能。

Grid優化

Ext JS Grid是造成Web應用性能問題的一個主要原因,尤其是在顯示大量數據的時候。當Grid在渲染小量數據的時候,速度不是問題。然而,在顯示大量數據的時候,如果不注意,虛擬的無限滾動就會成爲性能瓶頸。無限滾動依賴於頁面緩存分頁,也就是在用戶對Grid中進行滾動操作顯示數據之前,需要在分頁滾動對象內保存分頁數據。

當用戶滾動時,緩存數據就變成可見的,而消失在頁面頂部的則不再存放在DOM中。調整的主要途徑是讓讓DOM的大小儘可能的小,並在客戶端緩存數據從而減少與服務器的交互。

滾動原理

當Store的配置項buffered爲true時,會實例化一個PagingScroller對象用於監控視圖(Grid自帶的數據視圖)的滾動,同時要爲視圖即將進行的遍歷操作提供實時數據而緩存分頁數據。

下圖說明了用戶滾動時視圖獲取數據的方式。PageingScroller會在往前方向維持一個前導緩衝地帶,而在往後方向則維持一個小的後向緩存地帶。

PageingScroller


PagingScroller要求Store確保後向緩衝地帶和前導緩衝地帶都在緩衝中,這就需要計算那些頁面是需要的,以確保它們被緩存,而Store只需要通過Ajax請求不在緩存中的頁面。

當視圖往下滾動時,渲染表格的邊界將會進入視圖,當距離邊距numFromEdge行的時候,Store就要加載繼續往下的數據,同時保證垂直座標同步以保證可視行在相同位置。當所需數據在頁面緩存的時候,這個操作是在瞬間和無形中實現的。如果拖動滾動條超過了緩存頁面,將會發送yieldAjax請求,並顯示遮蔽直到數據返回。

如果滾動增量在一個合理的速度範圍內,請求區域的前導邊界進入另一不在緩存的頁面時,會調用Ajax請求該頁。在大多數情況下,如果前導緩衝區域足夠大,它會在在到達緩存行之前渲染表格。

默認情況下,頁面緩存只會緩存最近使用的5頁,這個根據瀏覽情況進行添加,讓更多的數據緩存在客戶端,從而減少Ajax請求。Store的purgePageCount配置項可控制該行爲。

如果數據不是太多,例如50000行,那可以將它們整個緩存到客戶端。設置Store的配置項purgePageCount爲0,頁面緩存後將不會被丟棄。

如何設計大表取決於如何渲染和瀏覽速度。表越大,在視圖到邊界及從預取緩衝到更新數據之間的滾動範圍就越多。然而,從預取緩衝中獲取的數據越多,重新渲染的時間就越長。這需要在可視數據與重新渲染之間要保持一個平衡。如果應用的目標是快速瀏覽器,可以選擇顯示更多的行和數據。如果是較慢的瀏覽器,則可使用顯示較小的行的較小的表,從而讓其更快到達可視邊界,適應經常的和更頻繁的刷新。

爲了協助你調試Grid,Ext JS 4.1包內Examples目錄下有一個名稱爲“Infinite Grid Tuner”的示例,它帶有1個5萬數據的數據集,可以讓你設置不同的方式通過預處理緩衝爲Store加載數據。例如,可以模擬Ajax的延時、修改預取數據的行數以及調整表的大小。你可以通過修改下圖左側上顯示的不同的參數,研究一下怎樣設置才能讓你的應用在瀏覽器上表現得更好。

Infinite Grid Tuner

通過Infinite Grid Tuner,你可以調整Store的purgePageCount設置。該設置會在渲染後從頁緩存中刪除大量數據。如果設置爲0,它會在緩存中保存所有數據,這意味着,如果用戶滾動Grid,將不需要從服務器中加載數據。

使用Infinite Grid Tuner,要清楚兩個概念:Grid內的可視數據可以被看作是一個滑動窗口。同樣,頁面緩存也可以被看作與Grid相關的滑動窗口的所有數據。你可以使用tuner改變兩者的大小,還可以爲它們分別補充規則,以確定從可視邊界到從Grid可視部分和頁面緩存獲取數據之間,用戶的滾動行數所在位置。

原文地址: http://www.mhzg.net/a/20123/2012368450567.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章