已有樹狀清單控制項分析發現問題
近期發現有人在ASP.NET項目開發中使用一種叫dtree的樹狀列表組件載入緩慢。這也是筆者撰寫本章的動機。毛主席教導我們,做事要發現問題,分析問題和解決問題。首先我們發現了已有的樹狀列表WEB控制項載入緩慢的問題,接下來就很自然的是分析問題了。
下圖就是dtree 運行介面的例子
分析問題
現在我們分析問題,對使用dtree產生樹狀列表的程式碼的分析,可以瞭解程式運行過程如下圖所示
在這樣的程式中,首先伺服器端的C#代碼查詢資料庫,然後根據查詢所得資料拼湊出一個Javascript代碼字串,然後發往用戶端,用戶端瀏覽器獲得這個Javascript代碼字串並開始執行它,而在Javascript指令碼中也是字串拼湊出一段HTML代碼字串,然後使用瀏覽器提供的 document.write方法或obj.innerHTML 屬性將產生的HTML字串填充到HTML頁面中進行展示。
這是是分析了dtree的流程,但使用其他的一些樹狀清單控制項也大體如此。
現在我們根據這個流程圖來判斷是哪個環節速度緩慢。基本上資料庫本身查詢速度是沒問題;將查詢結果傳遞到C#程式中問題也不大,因為一般的資料庫伺服器和ASP.NET程式是在一台電腦上或者同一個高速區域網路中;C#程式產生Javascript字串的過程也是沒多大問題,因為C#運行速度是相當的快的,而且還有StringBuilder來加速字串拼湊操作,因此只要邏輯演算法沒有問題,速度是有保障的。總體來說伺服器端內部是沒有速度問題。
將Javascript字串通過網路從伺服器端發送到用戶端,所花的的時間是字串長度除以網路傳輸速度,若WEB系統運行在高速的區域網路中,則速度沒多大問題,但若WEB程式運行在緩慢的廣域網路或英特網中,則Javascript字串長度會比較大的影響程式運行速度。由於公司系統主要運行在區域網路中,因此網路傳輸速度不是主要問題。
在用戶端瀏覽器中,瀏覽器接受並執行Javascript指令碼代碼,在Javascript指令碼中使用字串拼湊來產生用於展現樹狀列表的HTML 字串。Javascript代碼是解釋方式執行的,速度相當慢,而字串拼湊操作也是比較緩慢的操作,Javascript中沒有任何手段來最佳化字串拼湊操作。因此由Javascript代碼產生HTML字串的過程是緩慢的,這是一個速度瓶頸。
Javascript代碼還呼叫瀏覽器提供的document.write函數或innerHTML 屬性將產生的HTML字串填充到頁面中,瀏覽器會解析這個HTML代碼並展現出樹狀列表。由於document.write或innerHTML是運行在瀏覽器內部的,外部程式無法控制,而且速度也不算慢,因此這裡也就沒有什麼好最佳化的。
經過上述分析,可以看到整個展現樹狀列表的過程中最緩慢的環節就是使用Javascript指令碼來產生HTML代碼字串,其次就是資料從伺服器端發送到用戶端的過程。若一個樹狀列表要顯示數千個節點,則Javascript指令碼將拼湊出幾百K甚至過MB的HTML字串,這個過程是相當緩慢的,很容易導致IE瀏覽器由於指令碼運行過於緩慢而提示使用者是否繼續執行指令碼。
因此Javascript指令碼產生HTML字串將是我們主要的最佳化環節,也是新開發的樹狀清單控制項的重點關注部分。