日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

SAP Spartacus 的延迟加载 Lazy load 设计原理

發布時間:2023/12/19 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SAP Spartacus 的延迟加载 Lazy load 设计原理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

官方鏈接

延遲加載,也稱為代碼拆分,可讓您將 JavaScript 代碼分成多個塊。 結果是當用戶訪問第一頁時,您不必加載完整應用程序的所有 JavaScript。 相反,只加載給定頁面所需的塊。 在導航到其他頁面時,會在需要時加載其他塊。

這種方法可以顯著改善“交互時間”,尤其是在低端移動設備訪問復雜 Web 應用程序的情況下。

Spartacus Approach to Lazy Loading

代碼拆分是一種必須在應用程序構建時完成的技術。 Angular 提供的代碼拆分通常是基于路由的,這意味著著陸頁有一個塊,產品頁面有另一個塊,依此類推。

由于 Spartacus 主要是 CMS 驅動的,因此無法在構建時決定每個路由的實際應用邏輯。業務用戶最終將通過引入或刪除組件來改變頁面結構。 這就是為什么需要另一種延遲加載方法的原因,Spartacus 通過以下方式提供:

  • CMS 組件的延遲加載
  • CMS 驅動的功能模塊延遲加載 - CMS-driven lazy loading of feature modules

Defining Dynamic Imports Only in the Main Application

動態導入是一種用于促進延遲加載并允許代碼拆分的技術,只能在主應用程序 - main application 中使用。 無法在預構建庫中定義動態導入。

這是一個不幸的限制,導致必須由客戶添加一些應用程序代碼。 盡管自定義代碼的數量被限制在最低限度,但我們將在未來版本的 schematics library 中添加一項功能,以自動添加延遲加載模塊。

Avoiding Static Imports for Lazy-Loaded Code

為了使代碼拆分成為可能,您的靜態 JavaScript 代碼(主應用程序包)不應該對您想要延遲加載的代碼進行任何靜態導入。 如果你真的這么做了,構建器會注意到代碼已經包含在內,因此不會為其生成單獨的塊。 這在從庫中導入符號的情況下尤其重要。

在撰寫本文時(Angular 9 和 Angular 10),將靜態導入與動態導入混合用于相同的庫入口點,即使對于不同的符號,也會破壞該庫入口點的延遲加載和 tree shaking. 如果您要這樣做,它將在構建中靜態地包含整個入口點。 因此,強烈建議您為必須靜態加載的代碼創建特定的入口點,并為可以延遲加載的代碼創建單獨的入口點。

Configuration in Lazy-Loaded Modules

如果延遲加載模塊內部提供了額外的配置,Spartacus 會將其合并到全局應用程序配置中,以支持現有組件和服務的延遲加載場景。 在大多數情況下,尤其是當延遲加載的模塊主要提供默認配置時,這可以可靠地工作。 但是,如果過度使用它會導致問題,尤其是當兩個模塊為配置的同一部分提供不同的配置時。 可以通過在主應用程序中提供必要的覆蓋來修復諸如此類的場景。

這種合并功能是通過默認啟用的兼容性機制實現的,但您可以使用 disableConfigUpdates 功能標志禁用它。 如果您正在開發必須從延遲加載的模塊中掛鉤到配置的新模塊,則應改用 ConfigurationService.unifiedConfig$。 此功能在下一節中描述。

Unified Configuration

統一配置提供了一種獲取全局配置的方法,該配置包括根配置和來自已加載延遲加載模塊的配置。

ConfigurationService.unifiedConfig$ 將統一配置公開為每次更改時發出新配置的 observable。 例如,每次加載和實例化具有提供的配置的延遲加載模塊時都會發生這種情況。

所有配置部分都按照嚴格的順序合并,實際配置始終覆蓋默認配置,并且根模塊(即app shell)中定義的配置具有優先權。

以下示例顯示了根應用程序和兩個延遲加載模塊中提供的不同配置的合并順序,其中列表中的每個后續項都可以覆蓋前一項:

  • 默認根配置
  • 延遲加載模塊 1 的默認配置
  • 延遲加載模塊 2 的默認配置
  • 延遲加載模塊 1 的配置
  • 延遲加載模塊 2 的配置
  • 根配置(始終優先)

Providers in Lazy-Loaded Modules

延遲加載模塊中提供的注入令牌對根應用程序中提供的服務不可見。 這尤其適用于多提供的令牌,例如 HttpInterceptors、各種處理程序等。

為了減輕這個缺點,一些 Spartacus 功能,例如 PageMetaService(使用 PageMetaResolver 令牌)或 ConverterService(主要使用適配器序列化器和規范化器),后臺使用統一注入器。 通過這樣做,他們可以訪問延遲加載的令牌,并可以利用它們來實現全局功能。

對于不依賴于統一注入器的機制(例如,來自大多數非 Spartacus 庫的功能,例如核心 Angular 庫),建議您始終使用這些類型的令牌預先加載模塊。

unified injector

統一注入器提供了一種注入令牌或多提供令牌的方法,同時考慮到根注入器和來自延遲加載功能的注入器。 注入器公開一個可觀察的對象,每次統一注入器的狀態發生變化時,該觀察對象都會為指定的令牌發出一組新的可注入對象。

Avoiding Importing the HttpClientModule in Your Lazy-Loaded Modules

一般來說,HttpClientModule 應該在根應用程序中導入,而不是在庫中。 例如,如果您將它導入到延遲加載的庫中,則根庫中的所有注入器對于源自延遲加載模塊的 HTTP 調用都是不可見的。

雖然技術上可以在庫中導入 HttpClientModule ,但在大多數情況下這不是預期的,并且可能導致難以解釋的錯誤,因此請記住這一點。

Lazy Loading of CMS Components

Configuration of Lazy Loading CMS Components

CMS 代碼的延遲加載是通過在 CMS 映射配置中指定動態導入代替靜態引用的組件類來實現的。 下面是一個例子:

{cmsComponents: {SimpleResponsiveBannerComponent: {component: () => import('./lazy/lazy.component').then(m => m.LazyComponent)}} }

Technical Details

CMS 組件映射中對動態導入的支持是使用可定制的組件處理程序(特別是 LazyComponentHandler)實現的。

可以擴展此處理程序以自定義其行為、添加特殊鉤子或不同的觸發器,或者實現可以選擇性地重用現有處理程序的全新處理程序。

Lazy Loading of Modules

  • 懶加載不僅是組件代碼,還有核心部分(包括NgRx狀態)
  • 在第一次需要時只加載一次功能
  • 提供共享的、延遲加載的依賴模塊
  • 當實現被相關功能配置覆蓋時,CMS 請求組件會觸發功能模塊的延遲加載。

Configuration of Lazy-Loaded Modules

  • 功能模塊的動態導入(必須在主應用程序中定義)

  • 有關特定功能涵蓋哪些 CMS 組件的信息(可以成為庫的一部分并靜態導入)。 此信息以 cmsComponents 鍵下的字符串數組的形式提供。 下面是一個例子:

{featureModules: {organization: {module: () =>import('@spartacus/my-account/organization').then((m) => m.OrganizationModule),cmsComponents: ['OrderApprovalListComponent','ManageBudgetsListComponent','ManageCostCentersListComponent','ManagePermissionsListComponent','ManageUnitsListComponent','ManageUserGroupsListComponent','ManageUsersListComponent',],},}, }

例子:

[圖片上傳中…(image.png-c043ed-1625895062179-0)]

Component Mapping Configuration in Lazy-Loaded Modules

延遲加載模塊中的默認 CMS 映射配置應該以與靜態導入模塊完全相同的方式定義。

Spartacus 能夠從延遲加載功能中提取 CMS 組件映射配置,并使用它來解析該功能所涵蓋的組件類和工廠。 這就是為什么可以并推薦使用在延遲加載模塊中提供默認 CMS 映射配置的標準方式的原因。 因此,完全相同的模塊和庫入口點可以根據需要動態或靜態導入,并且仍然可以通過在應用程序中提供配置覆蓋來從應用程序級別覆蓋延遲加載的 CMS 配置。

Defining Shared-Dependency Modules

通過在功能配置的依賴項屬性中提供動態導入數組,可以將一些邏輯提取到共享的延遲加載模塊中,該模塊可以定義為功能模塊的延遲加載依賴項。 下面是一個例子:

{featureModules: {organization: {module: () =>import('@spartacus/my-account/organization').then((m) => m.OrganizationModule),dependencies: [() =>import('@spartacus/storefinder/core').then((m) => m.OrganizationModule),// ,,],},}, }

當延遲加載依賴它的第一個特性時,這種未命名的依賴模塊只會被實例化一次。 它的提供者為傳遞給特征模塊的組合注入器做出貢獻,因此,所有特征服務和組件都可以訪問依賴模塊提供的服務。

Combined Injector

任何延遲加載的模塊都可以從根應用程序注入器和依賴模塊注入器注入(即可以訪問)服務和令牌。 這是可能的,因為每次實例化具有依賴項的功能模塊時都會創建 CombinedInjector。

當一個被延遲加載模塊覆蓋的 CMS 組件被實例化時,它可以注入(即訪問)以下服務:

  • ModuleInjector 層次結構,從功能模塊注入器開始,包括依賴模塊和根注入器
  • ElementInjector 層次結構,在每個 DOM 元素上隱式創建

Initializing Lazy Loaded Modules

Spartacus 提供了一個 MODULE_INITIALIZER 來代替 Angular APP_INITIALIZER 來初始化延遲加載的模塊。

APP_INITIALIZER 機制在任何延遲加載發生之前完成應用程序的初始化,因此在加載時可能需要運行初始化邏輯的延遲加載功能無法這樣做。

MODULE_INITIALIZER 注入令牌可用于在旨在延遲加載的模塊中提供初始化函數。 MODULE_INITIALIZER 由 Spartacus 延遲加載機制支持,因此,使用 MODULE_INITIALIZER 提供的初始化函數將在它們定義的模塊被延遲加載之前運行。

您可以像配置 APP_INITIALIZER 一樣配置 MODULE_INITIALIZER。 下面是一個例子:

...import { MODULE_INITIALIZER } from '@spartacus/core';...export function myFactoryFunction(dependencyOne: DependencyOne ) {const result = () => {// add initialization logic here};return result; }@NgModule({providers: [{provide: MODULE_INITIALIZER,useFactory: myFactoryFunction,deps: [DependencyOne],multi: true,},], }) export class MyLazyLoadedModule {}

Preparing Libraries to Work with Lazy Loading

Providing Fine-Grained Entry Points in Your Library

在您的庫中提供細粒度的入口點。

從相同的入口點混合靜態和動態導入會破壞延遲加載并影響 tree-shaking,因此任何將直接用于動態導入的庫都應該公開細粒度的輔助入口點以優化代碼拆分。

作為慣例,Spartacus 暴露功能的根入口點,例如@spartacus/orgainzation/administration/root。 這種類型的入口點包含所有不應或不能延遲加載的代碼。 來自根入口點的模塊應該在根應用程序中靜態導入,這意味著它們將被預先加載并在主應用程序塊中可用。

Separating Static Code from Lazy-Loaded Code

當您使用 Angular Dependency Injection 時,注入器中的提供程序列表在注入器初始化后不應更改。這種范式特別適用于任何多提供的令牌、處理程序,尤其適用于任何 Angular 原生多提供的令牌,例如 HTTP_INTERCEPTOR、APP_INITIALIZER 等。

結果是延遲加載模塊中的任何多提供令牌對于根或其他延遲加載塊中提供的模塊和服務將不可見,但使用 unified injector 注入的多提供令牌除外。

一些 Spartacus 功能,例如 PageMetaService 或 ConverterService,使用 UnifiedInjector 來了解可以延遲加載的令牌,以便全局邏輯(例如 SEO 功能)即使邏輯延遲加載該功能也能可靠地工作。例如,商店定位器頁面元解析器可以在使用商店定位器功能的前提下,被延遲加載。

Spartacus 配置也是通過提供配置塊來定義的,由于兼容機制將配置從延遲加載功能貢獻到全局配置,因此處理方式略有不同。這種機制可以通過特性標志禁用,將來會默認關閉,以支持統一配置特性。

如果根服務無法看到延遲加載提供程序的問題,則始終可以將此類代碼包含在預先可用的靜態鏈接模塊中。建議在您的庫中創建一個單獨的入口點(按照慣例,命名為 root,例如 my-library/root),其中包含最少的代碼,將包含在主包中,并且從一開始就可用。

下面是客戶項目里 Lazy Load 的一個具體例子:

export const lazyLoadModules = {home: {module: () =>import('./custom/cms-components/home/home.module').then((m) => m.HomeModule),cmsComponents: ['ConnectWithUsComponent','StayConnectedComponent','DiabloUniverseBannerComponent','DiabloSupportBannerComponent','DiabloCommunityBannerComponent','WelcomeUserComponent','DiabloRewardsBannerComponent','ExclusiveForYouComponent','FeatureProductCarouselComponent','FeatureProductsComponent','TopBannerProductsComponent','ExclusiveForYouHeaderComponent','HomepageAdvantageHeadingParagraphComponent','DiabloAdvantagesCarouselBannerComponent',],},wishlist: {module: () =>import('./custom/cms-components/wish-list/custom-wish-list.module').then((m) => m.CustomWishListModule),cmsComponents: ['CustomWishListComponent'],},checkoutLogin: {module: () =>import('./custom/cms-components/user/custom-checkout-login/custom-checkout-login.module').then((m) => m.CustomCheckoutLoginModule),cmsComponents: ['CustomCheckoutLoginComponent'],},login: {module: () =>import('./custom/cms-components/user/custom-login/custom-login.module').then((m) => m.CustomLoginModule),cmsComponents: ['CustomLoginComponent'],},loginForm: {module: () =>import('./custom/cms-components/user/custom-login-form/custom-login-form.module').then((m) => m.CustomLoginFormModule),cmsComponents: ['CustomLoginFormComponent'],},orderConfirmation: {module: () =>import('./custom/cms-components/order-confirmation/order-confirmation.module').then((m) => m.OrderConfirmationModule),cmsComponents: ['CustomOrderConfirmationOverviewComponent','CustomOrderConfirmationThankYouMessageComponent','CustomOrderConfirmationItemsComponent','CustomOrderConfirmationTotalsComponent',],},header: {module: () =>import('./custom/cms-components/navigation/header/custom-header.module').then((m) => m.CustomHeaderModule),cmsComponents: ['CustomCategoryNavigationComponent','CustomHamburgerMenuComponent','CustomNavigationUIComponent','CustomSearchBoxComponent','DiabloRewardsComponent','CustomHeaderNavigationComponent',],},footer: {module: () =>import('./custom/cms-components/navigation/footer/custom-footer.module').then((m) => m.CustomFooterModule),cmsComponents: ['CustomFooterNavigationComponent','ExtendedFooterNavigationComponent','CustomFooterNavigationUIComponent',],},product: {module: () =>import('./custom/cms-components/product/product.module').then((m) => m.ProductModule),cmsComponents: ['NewSearchBoxComponent','EmptySearchMessageComponent','SearchSuggestionsMessageComponent','ContactUsComponent','SupportComponent','ChatComponent','ChatDetailsComponent','ChatLinkComponent','EmailComponent','EmailDetailsComponent','EmailLinkComponent','PhoneComponent','PhoneNumberComponent','PhoneLinkComponent','PhoneDetailsComponent','CommunityComponent','CommunityDetailsComponent','CommunityLinkComponent','InternationalAssistanceComponent','InternationalAssistanceDetailsComponent','PDPTabNavComponent','ProductImagesComponent','ProductIntroComponent','ProductSummaryComponent','AddToWishListComponent','ProductHighlightsComponent','ProductOffersComponent','PDPReturnPolicyComponent','supportTabComponent','WarrantyTabComponent','PDPServiceComponents','ProductReviewComponent','CrossSelling','Similar','PDPQuestionsComponent','ProductLegalComponent','ProductSpecificationComponent','PDPFeatureSlotComponent','Frequently_Bought_Together',],}, };// CustomConsentManagementModule, // ProductModule, // MyAccountModule, // CustomCheckoutModule, // CustomCardModule, // CustomMainModule, // CustomIconModule, // CustomNotificationPreferenceModule, // CustomBreadcrumbModule, // CustomOccModule, // CustomCmsOccModule, // CustomFooterModule, // CustomLoginModule, // CustomHeaderModule, // CustomMiniCartModule, // CustomGenericLinkModule, // CustomCartDetailsModule, // OrderConfirmationModule, // CustomCartCouponModule, // CustomCartTotalsModule, // CustomCartSharedModule, // CustomItemCounterModule, // GenericParagraphModule, // CustomLoginFormModule, // IconModule, // HomeModule, // CustomWishListModule, // CustomCheckoutLoginModule, // CustomCheckoutOccModule, // CustomAuthStoreModule, // BrowserTransferStateModule, // CustomCmsParagraphModule, // I18nModule,

總結

以上是生活随笔為你收集整理的SAP Spartacus 的延迟加载 Lazy load 设计原理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。