Lazy loading, also known as code splitting, lets you divide your JavaScript code into multiple chunks. The result is that you do not have to load all the JavaScript of the full application when a user accesses the first page. Instead, only the chunks that are required for the given page are loaded.

懒加载可以允许我们将TypeScript编译出的JavaScript代码拆分成若干个chunk, 这样,当应用程序加载时,我们无需将整个应用所需的所有chunk都加载到浏览器中,而是可以实现按需加载的机制,即仅加载那些需要渲染的页面对应的chunk.

我们在Angular项目里执行命令行ng build,即可查看打包出来的chunk名称和对应的大小,如下图所示。

默认情况下,我们在Angular应用里编写的所有Component,会被ng build打包到一个main chunk里。比如我开发了一个MyCartComponent:

打包到main chunk后对应的JavaScript代码如下:

如何让一个Angular应用的Component支持lazy load,即将其和main chunk分开进行打包呢?

看个例子。

在AppRoutingModule里,配置路由信息时,不使用常规的Component属性,而是采用loadChildren,为某个path动态地指定要加载的Component名称:

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

const routes: Routes = [
  {
    path: 'customers',
    loadChildren: () => import('./customers/customers.module').then(m => m.CustomersModule)
  },
  {
    path: 'orders',
    loadChildren: () => import('./orders/orders.module').then(m => m.OrdersModule)
  },
  {
    path: '',
    redirectTo: '',
    pathMatch: 'full'
  }
];

@NgModule({
  imports: [
    RouterModule.forRoot(routes)
  ],
  exports: [RouterModule],
  providers: []
})
export class AppRoutingModule { }

看看customers.module.ts的实现:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { CustomersRoutingModule } from './customers-routing.module';
import { CustomersComponent } from './customers.component';

@NgModule({
  imports: [
    CommonModule,
    CustomersRoutingModule
  ],
  declarations: [CustomersComponent]
})
export class CustomersModule { }

里面导入了另一个CustomersRoutingModule:

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

import { CustomersComponent } from './customers.component';

const routes: Routes = [
  {
    path: '',
    component: CustomersComponent
  }
];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})
export class CustomersRoutingModule { }

这里才是常规的Angular router定义机制,path和component 字段pair的组合。

执行ng build之后,这次发现main chunk和customers以及orders chunk分别进行打包了,这说明Customers和Orders的lazy loading启用生效了。

在运行时能看得更清楚。浏览器里访问应用,因为没有打开customers或者orders页面,因此没有加载对应的chunk:

点击customers超链接:

直到此时,才观察到了customers chunk,这就是Angular Component 懒加载模式在运行时的表现效果。

Lazy loading, also known as code splitting, lets you divide your JavaScript code into multiple chunks. The result is that you do not have to load all the JavaScript of the full application when a user accesses the first page. Instead, only the chunks that are required for the given page are loaded. While navigating the storefront, additional chunks are loaded when needed.

code splitting技术发生在application build期间。

Code splitting provided by Angular is typically route-based, which means there is a chunk for the landing page, another chunk for the product page, and so on.

Angular Code split基于路由的,比如landing page分配一个代码chunk,product page分配另一个代码chunk,以此类推。

Since Spartacus is mostly CMS driven, the actual application logic for each route cannot be decided at build time. Business users will eventually alter the page structure by introducing or removing components.

在Spartacus里,每个route的应用逻辑无法在build阶段知晓,因为Spartacus是CMS驱动的,business user可以通过添加或者移除Component的方式来影响页面结构。


ConfigModule.withConfig({
      cmsComponents: {
        BannerComponent: {
          component: () =>
            import('./lazy/lazy-banner.component').then(
              (m) => m.LazyBanner
            ),
        }
      }
    }),

这个lazy-lazy-banner-component.js.map在哪里?ng build即可看到。

To make code spitting possible, your static JavaScript code (the main app bundle) should not have any static imports to code that you want to lazy load. The builder will notice that the code is already included, and as a result, will not generate a separate chunk for it. This is especially important in the case of importing symbols from libraries.

衡量lazy load的标志就是,builder为code生成单独的chunk.

更多Jerry的原创文章,尽在:"汪子熙":


注销
1k 声望1.6k 粉丝

invalid