最近工作中處理了 SAP Commerce Cloud (電商雲) UI 的一個懶載入 (Lazy Load) 功能的問題,這裡把自己學到的東西做個記錄。
UI 懶載入,有時又稱惰性載入,延遲載入,是和貪婪載入 (Eager Load) 截然相反的一種 UI 元件載入策略。
假設一個應用的 UI 由 A,B,C 若干檢視組成,採用貪婪載入,則所有檢視的實現程式碼,在 build 階段會被合併到一個程式碼塊中,在 UI 載入領域裡,這種程式碼塊的術語為 chunk. 在貪婪載入模式下,所有檢視實現程式碼合併成的單一程式碼塊,通常稱為 main chunk. 在使用者瀏覽器訪問應用的任何一個檢視,比如檢視 A 時,包含了該應用所有檢視實現程式碼的 main chunk 會被瀏覽器載入。當應用的規模趨於複雜時,採用貪婪載入模式 build 而成的 main chunk 尺寸也隨之變大,會影響應用的首屏載入時間。
假設一個應用的部分檢視和首屏載入無關,而是使用者開啟應用首頁後,需要點選某些連結,跳轉之後才能開啟。為了減少應用的首屏載入時間,我們可以考慮將這部分檢視採用懶載入的方式,分別進行 build,從而生成多個 chunk, 並按需被瀏覽器載入。
下面用 SAP Commerce Cloud (電商雲) 為例來具體說明。
Jerry 之前的文章 從一個實際的例子出發,談談 SAP Commerce Cloud (電商雲) 的 UI 自定義開發 曾經提到了購物車頁面的自開發場景。
這個購物車頁面,需要使用者成功載入 Commerce Cloud 首頁後,點選右上角的購物車圖示才能夠顯示:
然而預設情況下,該購物車的自開發元件,MyCartComponent,還是被預設打包到 main chunk 內。我們可以用文字編輯器,開啟名為 main-es2015.js 的main chunk 檢視其內容。
下圖是自開發 MyCartComponent 的 TypeScript 實現:
被 Angular 編譯器編譯成 JavaScript 程式碼後,其對應程式碼能夠在 main-es2015.js 裡找到:
執行時,儘管客戶僅僅訪問了 SAP Commerce Cloud 首頁,沒有點選購物車,然而因為購物車自開發元件遵循的預設貪婪載入模式,因此其實現程式碼仍然被包含在了 main chunk 裡,隨首屏一併載入。
下面我們就來試試,用懶載入模式,來載入SAP Commerce Cloud (電商雲) 的自開發元件。
因為前一篇文章,我們已經使用了自開發購物車作為例子,本文就換一個例子來闡述。
SAP Commerce Cloud (電商雲) 頁面上這種能夠透過點選,跳轉到產品明細頁面的圖片控制元件,稱之為 Banner,當然也是能夠定製開發的:
比如我新建了一個 Lazy Banner Component,裡面啥邏輯都沒有,就列印一行硬編碼的 I am lazy 的字串:
在app.module.ts 裡啟用我自開發的 LazyBanner 元件之後:
SAP Commerce Cloud 的 UI 渲染如下:
現在更改程式碼,以懶載入的方式,啟用自開發元件 LazyBanner 的載入:
透過比較兩種載入模式的程式碼能發現,利用 Angular 動態 import 語句,阻止了 builder 將 LazyBanner 元件的實現打包到 main chunk 的行為。
執行 ng build, 這次就能發現,LazyBanner 元件的實現已經和 main chunk 分開進行打包了,生成了一個單獨的 chunk:
該 LazyBanner 元件生成的 chunk 的 JavaScript 原始碼如下:
而在執行時,透過 Chrome 開發者工具,我們也能觀察到,LazyBanner 元件對應的 chunk,是和 main chunk 分開進行載入的。
在實際專案實施過程中,如果一個自開發元件的規模過於龐大,並且和首屏載入邏輯無關,則可考慮透過懶載入的方式,將其同 main chunk 剝離開,從而減少首屏載入時間。
另外,SAP UI5 也同樣支援懶載入機制,SAP UI5 的從業者,可以移步這篇文章進行學習。感謝大家的閱讀。
更多Jerry的原創文章,盡在:"汪子熙":