SAP 电商云 Spartacus UI 4.1 版本的延迟加载技术介绍
延遲加載,也稱為代碼拆分,可讓您將 JavaScript 代碼分成多個塊。 結果是當用戶訪問第一頁時,您不必加載完整應用程序的所有 JavaScript。 相反,只加載給定頁面所需的塊。 在瀏覽店面時,會在真正需要使用到某些功能時,再加載這些功能塊的實現模塊。
這種方法可以顯著改善“交互時間”,尤其是在低端移動設備訪問復雜 Web 應用程序的情況下。
Spartacus Approach to Lazy Loading
代碼拆分是一種必須在應用程序構建時完成的技術。 Angular 提供的代碼拆分通常是基于路由的,這意味著著陸頁有一個塊,產品頁面有另一個塊,依此類推。 由于 Spartacus 主要是 CMS 驅動的,因此無法在構建時決定每個路由的實際應用邏輯。 業務用戶最終將通過引入或刪除組件來改變頁面結構。 這就是為什么需要另一種延遲加載方法的原因,Spartacus 支持以下兩種不同粒度的延遲加載技術:
- CMS 組件的延遲加載
- CMS 驅動的功能模塊延遲加載
Defining Dynamic Imports Only in the Main Application
動態導入是一種用于促進延遲加載并允許代碼拆分的技術,只能在類型為 Application 的 Angular 應用程序中使用。無法在預構建庫(類型為 Library )中定義動態導入。
這是一個不幸的限制,導致必須由客戶添加一些應用程序代碼。 盡管自定義代碼的數量被限制在最低限度,但我們將在未來版本的原理圖庫中添加一項功能,以自動添加延遲加載模塊。
Avoiding Static Imports for Lazy-Loaded Code
為了使代碼拆分成為可能,您的靜態 JavaScript 代碼(主應用程序包)不應該對您想要延遲加載的代碼進行任何靜態導入。一個例子就是 QuickOrderService. 構建器會注意到代碼已經包含在內,因此不會為其生成單獨的塊。 這在從庫中導入 symbol 的情況下尤其重要。
至少在 Angular 9 和 Angular 10 里,將靜態導入與動態導入混合用于相同的庫入口點,即使對于不同的 symbol,也會破壞該庫入口點的延遲加載和 tree shaking 優化。 如果您要這樣做,它將在構建中靜態地包含整個入口點。 因此,強烈建議您為必須靜態加載的代碼創建特定的入口點,并為可以延遲加載的代碼創建單獨的入口點。
Configuration in Lazy-Loaded Modules
如果在延遲加載模塊內部提供了額外的配置,Spartacus 會將其合并到全局應用程序配置中,以支持現有組件和服務的延遲加載場景。 在大多數情況下,尤其是當延遲加載的模塊主要提供默認配置時,這可以可靠地工作。 但是,如果過度使用它會導致問題,尤其是當兩個模塊為配置的同一部分提供不同的配置時。 可以通過在主應用程序中提供必要的覆蓋來修復諸如此類的場景。
這種合并功能是通過默認啟用的兼容性機制實現的,但您可以使用 disableConfigUpdates 功能標志禁用它。 如果您正在開發必須從延遲加載的模塊中掛鉤到配置的新模塊,則應改用 ConfigurationService.unifiedConfig$。
Providers in Lazy-Loaded Modules
延遲加載模塊中提供的注入令牌對根應用程序中提供的服務不可見。
這尤其適用于 multi-provided 的令牌,例如 HttpInterceptors、各種處理程序等。
為了減輕這個缺點,一些 Spartacus 功能,例如 PageMetaService(使用 PageMetaResolver 令牌)或 ConverterService(主要使用適配器序列化器和規范化器),在我們的實現里使用 unified 注入器。 只有這樣做,根應用程序才可以訪問延遲加載的令牌,并可以利用它們來實現全局功能。
對于不依賴于統一注入器的機制(例如,來自大多數非 Spartacus 庫的功能,例如核心 Angular 庫),建議您始終使用 eager 模式加載包含了這些令牌的模塊。
Unified Injector
統一注入器提供了一種注入令牌或多提供令牌的方法,這種方法同時考慮到根注入器和來自延遲加載功能的注入器。 注入器公開一個可觀察的對象,每次統一注入器的狀態發生變化時,該觀察對象都會為指定的令牌發出一組新的可注入對象。
Avoiding Importing the HttpClientModule in Your Lazy-Loaded Modules
一般來說,HttpClientModule 應該在根應用程序中導入,而不是在庫中。 例如,如果您將它導入到延遲加載的庫中,則根庫中的所有注入器對于源自延遲加載模塊的 HTTP 調用都是不可見的。
雖然技術上可以在庫中導入 HttpClientModule ,但在大多數情況下這不是預期的,并且可能會導致難以解釋的錯誤,因此請記住這一點。
Lazy Loading of CMS Components
CMS 代碼的延遲加載是通過在 CMS 映射配置中指定動態導入代替靜態引用的組件類來實現的。 下面是一個例子:
{cmsComponents: {SimpleResponsiveBannerComponent: {component: () => import('./lazy/lazy.component').then(m => m.LazyComponent)}} }Lazy Loading of Modules
CMS 驅動的功能模塊延遲加載允許以下內容:
- 懶加載不僅是組件代碼,還有核心部分(包括NgRx狀態)
- 在第一次需要時只加載一次功能提供共享的、延遲加載的依賴模塊
- 當實現被相關功能配置覆蓋時,CMS 請求組件會觸發功能模塊的延遲加載。
Exposing Smart Proxy Facades From lazy loaded Features
代理外觀提供了一種靈活的方式來從延遲加載的功能模塊中公開核心功能,這樣使用這些外觀的組件就不必知道它是否延遲加載以及是否需要初始化。
對代理外觀的方法或屬性的任何訪問都會觸發所有相關功能的延遲加載和初始化。
Combined Injector
任何延遲加載的模塊都可以從根應用程序注入器和依賴模塊注入器注入(即可以訪問)服務和令牌。 這是可能的,因為每次實例化具有依賴項的功能模塊時都會創建 CombinedInjector。
當一個被延遲加載模塊覆蓋的 CMS 組件被實例化時,它可以注入(即訪問)以下服務:
- ModuleInjector 層次結構,從功能模塊注入器開始,包括依賴模塊和根注入器
- ElementInjector 層次結構,它是在每個 DOM 元素上隱式創建的
Preparing Libraries to Work with Lazy Loading
Providing Fine-Grained Entry Points in Your Library
從相同的入口點混合靜態和動態導入會破壞延遲加載并影響搖樹,因此任何將直接用于動態導入的庫都應該公開細粒度的輔助入口點以優化代碼拆分。
作為慣例,Spartacus 公開功能的根入口點(root entry points),例如 @spartacus/orgainzation/administration/root。 這種類型的入口點包含所有不應或不能延遲加載的代碼,比如 Proxy Facade 層。來自根入口點的模塊應該在根應用程序中靜態導入,這意味著它們將被預先加載并在主應用程序塊中可用。
有關對 Angular 庫中輔助入口點的支持的更多信息,請參閱 GitHub 上 ng-packagr 文檔中的輔助入口點。
Separating Static Code from Lazy-Loaded Code
當您使用 Angular Dependency Injection 時,注入器中的提供程序列表不應在注入器初始化后更改。這種范式特別適用于任何多提供的令牌、處理程序,尤其適用于任何 Angular 原生多提供的令牌,例如 HTTP_INTERCEPTOR、APP_INITIALIZER 等。
結果是延遲加載模塊中的任何多提供令牌對于根或其他延遲加載塊中提供的模塊和服務將不可見,但使用注入的多提供令牌除外統一噴油器。
一些 Spartacus 功能,例如 PageMetaService 或 ConverterService,使用 UnifiedInjector 來了解可以延遲加載的令牌,以便全局邏輯(例如 SEO 功能)即使邏輯延遲加載該功能也能可靠地工作。例如,商店定位器頁面元解析器可以使用商店定位器功能延遲加載。
Spartacus 配置也是通過提供配置塊來定義的,由于兼容機制將配置從延遲加載功能貢獻到全局配置,因此處理方式略有不同。這種機制可以通過功能標志禁用,將來會默認關閉,以支持統一配置功能。
如果根服務無法看到延遲加載提供程序的問題,則始終可以將此類代碼包含在預先可用的靜態鏈接模塊中。建議在您的庫中創建一個單獨的入口點(按照慣例,命名為 root,例如 my-library/root),其中包含最少的代碼,將包含在主包中,并且從一開始就可用。
Simple Strategies for Optimized and Balanced Code Splitting
每個業務功能都略有不同,但總的來說,出于折中考慮,可以按照以下幾點進行優化:
-
大多數功能都提供了一系列 UI 組件,如果您訪問一個組件,很可能很快也會需要其他組件。為了最大限度地減少網絡流量和不必要的粒度開銷,您可以考慮在同一個 chunk 中捆綁多個組件。
-
功能的大多數 UI 組件通常需要核心邏輯。何謂核心?例如 Facade 的實現類即 Service, 以及適配器。在這種情況下,您可以考慮使用 lazy loading 機制來加載 core 模塊。
-
一個特性的一些核心服務也可能被其他 feature 頻繁使用。在這種情況下,您可以考慮將核心代碼與 UI 組件分開。
功能的某些部分使用非常頻繁(例如每個頁面都使用的購物車圖標組件),而有些僅在某些特定場景中使用(例如購物車摘要)。為了獲得最佳體驗,建議根據使用情況將功能拆分為邏輯部分,并為最少、最需要的部分創建單獨的入口點(和功能),并為不太常用的代碼創建另一個入口點。
總結
以上是生活随笔為你收集整理的SAP 电商云 Spartacus UI 4.1 版本的延迟加载技术介绍的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一原始股等于多少股票
- 下一篇: SD女佣怎么使用 SD女佣使用教程