改善Dojo應用程式的初始下載時間

CloudSpace發表於2008-07-25
載入 Ajax 應用程式之後,隨後它將獲取較小的資料和內容片段,以避免重新呈現整個頁面的開銷,從而提高效能。這樣做的代價是,應用程式的初始下載時間通常會較長。本文將討論如何減少 Dojo 應用程式的初始下載時間並同時獲得很好的效能。

僅獲取所需的資料

Asynchronous JavaScript. and XML (Ajax) 應用程式能夠提高某些 Web 應用程式的效能。載入應用程式之後,獲取較小的資料和內容片段可以幫助避免重新呈現整個頁面的開銷。不過,這樣做得的代價是,應用程式的初始下載時間通常會比較長。

我現在已有多年的 Dojo 應用程式使用經驗。IBM® WebSphere® Application Server Feature Pack for Web 2.0Project Zero 現在都包括 Dojo Toolkit 的 IBM 分發版本,提供了一些增值擴充套件。由於 Dojo Toolkit 的模組化特性,初始載入可能會花費相當長的時間,因為使用的每個模組可能都需要下載一些 JavaScript™、HTML 和 CSS 檔案。這會在網路上帶來大量額外的 IO 操作,遠遠超過每個模組本身的大小。

通常,這個模組化特徵是程式設計師所必需的,因為通過其可以方便地進行除錯和編碼,但編寫了應用程式之後,此模組化特徵就不再重要了——或不再需要了。您可以通過多種方法減少 Dojo 應用程式的初始下載時間。

使用 Dojo 構建和打包系統

Dojo Toolkit 提供了打包和壓縮技術,用於將在應用程式中使用的 Dojo 程式碼打包為單個檔案,然後使用名為 Dojo ShrinkSafe 的壓縮技術將其壓縮到最小尺寸。大部分 Dojo 應用程式都應該將此技術作為其部署的一部分使用,因為此技術將極大地提高應用程式的效能(特別是初始下載時間)。您只需要為應用程式建立概要,並在其中指定要使用哪個 Dojo 元件。清單 1 顯示了一個示例。


清單 1. 示例概要
                
dependencies ={

    layers:  [
        {
        name: "example.js",
        dependencies: [
			
			"dojo.*",
			"dojo.parser",
			"dijit.dijit",
			"dijit.Declaration",
			"dijit.layout.LayoutContainer",
			"dojox.layout.ContentPane",
			"dijit.Toolbar",
			"dijit.layout.AccordionContainer",
			"my.widget.Super"         
       	]
        }
    ],
	
	
    prefixes: [
        
		[ "dijit", "../dijit" ],
		[ "my", "/myWidgets"],
		[ "dojox", "../dojox" ]
    ]

};

然後您將執行命令列構建工具,使用各種選項傳入概要。Dojo 構建然後將應用程式所需的所有程式碼(包括 JavaScript、HTML 和 CSS)放入單個檔案中,並對其進行壓縮。通過使用此方法,我發現在應用程式初始下載中,IO 呼叫的數量可能從 200 個以上減少到 2 個或 3 個。我還發現總體大小減少了約 60%。將很快推出關於使用 Dojo 構建和打包系統的 developerWorks 教程,不過在 Dojo 網站上提供了關於打包系統和自定義構建的更多資訊。

延遲載入和快取 Dojo 內容

可以極大減少初始下載大小的另一個方法是,對頁面的內容部分進行延遲載入,並在載入之後對其進行快取。有時候,這樣的做法會更好:不在首次訪問應用程式時就載入所需的所有東西,而僅在這個時候載入應用程式的部分內容。使用者完全可能會在訪問站點時從來不會訪問 Web 應用程式的某些特定部分,因此下載這些不會接觸的部分所消耗的時間都浪費掉了。所以,您並不需要下載應用程式中可能不會使用的部分。而且,第一印象極為重要:如果不能快速顯示初始主頁,可能會讓使用者更快放棄使用您的程式。

通常,您會希望載入包含初始選單的佈局,然後在載入之後獲取主頁內容。常見 Dojo 應用程式通常由一些佈局元素組成。請看清單 2:


清單 2. 佈局
                

	

通過清單 2 可以瞭解一些事項。我建立了一個簡單的方法來將 HTML 片段載入到特定的內容中。我還使用 dojox.layout.ContentPane 替代了預設 dijit。擴充套件的內容窗格允許在載入區域時執行 JavaScript。通過這樣,不僅可以延遲載入 HTML 內容,還可以採用延遲載入方式載入關聯的邏輯。清單 3 顯示了我所編寫的實用方法的實現。


清單 3. 延遲載入
                
var loaded = new dojox.collections.Dictionary();

function hideAll()
{
	console.debug("Hiding other content");
	var ids = loaded.getKeyList();
	console.debug("Getting ID -> " + ids);
	console.debug("List is Array");
	for (var id in ids) {
		console.debug("Getting section -> " + ids[id]);
		var section = dijit.byId(ids[id]);
		console.debug("Got Section -> " + section);
		if (section) {
			console.debug("setting DOM");
			section.domNode.style.display = "none";
		}
	}
	console.debug("Content is hid");
}

function showItem(key,template)
{
	hideAll();
	console.debug("Show Item -> " + key);
	var item = dijit.byId(key);	
	console.debug(item);
	if (item) 
	{
		if(!loaded.contains(key))
		{
			item.setHref(template);
			item.refresh();
			loaded.add(key,template);
		}
		
		item.domNode.style.display ="block";
	}
}

/**
 * Load Default page
 */
dojo.addOnLoad(function loadDefault()
{
	console.debug("Loading initial state");
	showItem('productList','product/product.html');
});

在清單 3 中呼叫 showItem 時,我隱藏了在主體中可能可見的任何內容。我然後進行檢查,確定是否載入了 HTML。如果未載入,將下載模板,然後將其快取在 Dojo 詞典中。下次請求此頁面時,將會直接顯示該區域。我還使用 dojo.addOnLoad 方法載入預設頁面。

在清單 3 中呼叫 showItem 時,我隱藏了在主體中可能可見的任何內容。我然後進行檢查,確定是否載入了 HTML。如果未載入,將下載模板,然後將其快取在 Dojo 詞典中。下次請求此頁面時,將會直接顯示該區域。我還使用 dojo.addOnLoad 方法載入預設頁面。

不要全部使用 dijit

我們很可能喜歡為主要應用程式元件建立 dijit(Dojo 小部件)。例如,在清單 4 中,可以看到將應用程式處理為 Dojo dijit 的示例。


清單 4. 將應用程式處理為 dijit 可以減少下載時間
                

在清單 4 中,我將每個應用程式元件都包裝在 dijit 中。反過來,每個 dijit 都由子 dijit 組成。甚至可以將載入整個應用程式視為超 dijit:

問題是,您忽略了延遲載入內容(或太過複雜而不能考慮這個選項),特別在構建中包括所有小部件的情況下。我發現,最好為 UI 元件(Data Grid、專用組合框、特殊文字區)建立 dijit,然後載入使用 dijit 的普通 HTML 模板。

通過遵循一些指導原則和實踐,可以很容易地減少下載應用程式的時間,而且仍然能夠獲得 Dojo 具有的一些效能優勢。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/14789789/viewspace-410134/,如需轉載,請註明出處,否則將追究法律責任。

相關文章