수동 느린 로드 각도

Angular 엔터프라이즈 응용 프로그램에서는 일반적으로 UI 구성을 포함하는 HTTP 요청을 통해 서버에서 구성을 로드해야 합니다.이 구성 데이터를 기반으로 여러 모듈 및/또는 구성 요소를 로드하고 라우팅을 애플리케이션에 동적으로 추가해야 합니다.
이 블로그 글에서, 나는 Angular 9+를 사용하여 실행할 때 모듈과 구성 요소를 지연시키는 방법을 보여 주고 싶다.
StackBlitz demo는 다음 장에서 기술한 코드를 포함한다.
프레젠테이션의 소스 코드는 GitHub 에서 얻을 수 있습니다.

라우터 지연 로드 모듈 사용


Lazy Loading: Load it when you need it


Angular 8 때문에 브라우저 내장 dynamic imports 을 사용하여 Angular에서 JavaScript 모듈을 비동기적으로 로드할 수 있습니다.import(...) 의 새 loadChildren 구문을 사용하여 라우팅 구성에서 로드 지연 모듈을 정의할 수 있습니다.
@NgModule({
  imports: [
    RouterModule.forRoot([
      {
        path: 'lazy',
        loadChildren: () =>
          import('./lazy/lazy.module').then(m => m.LazyModule),
      },
    ]),
  ],
})
export class AppModule {}
Angular 8 (또는 이전 버전) 을 사용하려면 loadChildren: './lazy/lazy.module#LazyModule 구문을 지원하지 않기 때문에 Angular 라우터를 사용하는 모듈의 로드 지연을 사용하려면 import(...) 을 작성해야 합니다.
Angular CLI는 선택한 라우팅이 활성화된 경우에만 서버에서 로드되는 별도의 JavaScript 패키지를 자동으로 생성합니다.
모듈의 모든 LazyModule 그룹에 imports 을 추가하면 즉시 불러옵니다.

수동 지연 로드 모듈


때때로, 로드 지연 과정에 대해 더 많은 제어를 원하고, 어떤 이벤트(예를 들어 단추를 누르면)가 발생한 후에 로드 과정을 터치하기를 원합니다.일반적으로 이 이벤트가 발생한 후에는 백엔드의 HTTP 호출과 같은 비동기식 리소스에 액세스하여 로드가 지연되는 모듈 및/또는 구성 요소에 대한 정보를 포함하는 구성 파일을 가져옵니다.
demo 중에서 나는 LazyLoaderService 이러한 행동을 보여 주었다.
@Injectable({
  providedIn: 'root',
})
export class LazyLoaderService {
  private lazyMap: Map<string, Promise<unknown>> = new Map();

  constructor() {}

  getLazyModule(key: string): Promise<unknown> {
    return this.lazyMap.get(key);
  }

  loadLazyModules(): Observable<number | void> {
    return of(1).pipe(
      delay(2000),
      tap(() => {
        this.lazyMap.set(
          'lazy',
          import('./lazy/lazy.module').then(m => m.LazyModule)
        );
      })
    );
  }
}
loadLazyModules 방법은 백엔드 요청을 시뮬레이션합니다.요청이 성공하면 import(...) 구문 등록 모듈을 사용합니다.응용 프로그램을 실행하면 모듈에 별도의 블록이 만들어졌지만 브라우저에 로드되지 않았습니다.

모듈promise는 Map에 저장되어 있으며, 나중에 접근할 수 있도록 키를 가지고 있습니다.
이제 onClickAppComponent 프로세서에서 이 방법을 호출하여 라우터 구성에 라우팅을 동적으로 추가할 수 있습니다.
  constructor(
    private router: Router,
    private lazyLoaderService: LazyLoaderService
  ) {}

  loadLazyModule(): void {
    this.lazyLoaderService.loadLazyModules().subscribe(() => {
      const config = this.router.config;
      config.push({
        path: 'lazy',
        loadChildren: () => this.lazyLoaderService.getLazyModule('lazy')
      });
      this.router.resetConfig(config);
      this.router.navigate(['lazy']);
    });
  }
우리는 의존 주입을 통해 공유기에서 현재의 공유기 설정을 얻고 우리의 새로운 루트를 끌어들인다.
라우팅 구성에 와일드카드 라우팅(**이 있는 경우 주의하십시오.와일드카드 라우팅은 각 URL이 일치하고 다른 라우팅이 먼저 일치하지 않을 때만 선택되기 때문에 라우팅 배열의 마지막 색인에 항상 있어야 합니다.
다음은 호출 resetConfig 을 통해 내비게이션과 링크 생성에 사용되는 공유기 설정을 재설정해야 합니다. 새로운 설정은 로드 지연 모듈 루트를 포함합니다.마지막으로 새로 로드된 경로로 이동하여 유효한지 확인합니다.

Load Lazy Module(Load Lazy Module) 버튼을 클릭하면 다음과 같은 세 가지가 표시됩니다.
  • 서버에서 지연 모듈을 요청하는 블록, 마운트 표시기 보이기
  • 로드가 완료되면
  • 브라우저 URL이 새 라우팅으로 변경됩니다/lazy
  • 로드가 지연되는 모듈LazyHomeComponent
  • 도구 모음에 새 항목 보이기
  • 반복 app.component.html 라우터 구성에서 사용 가능한 라우팅을 통해 도구 모음에서 사용 가능한 라우팅을 동적으로 표시합니다.
    <mat-toolbar color="primary">
      <mat-toolbar-row>
        <a
          class="router-link"
          *ngFor="let route of routes"
          [routerLink]="route.path"
          routerLinkActive="active-link"
          >{{ route.path | uppercase }}</a
        >
      </mat-toolbar-row>
    </mat-toolbar>
    

    로드가 지연되는 라우팅에 책갈피 추가


    일반적인 요구 사항은 사용자가 응용 프로그램의 일부 URL에 자주 액세스할 때 이러한 URL에 대한 책갈피를 만드는 것입니다.우리는 현재의 실현 과정에서 시도해 봅시다.

    지연 라우트를 다시 로드하면 오류가 발생합니다. Error: Cannot match any routes. URL Segment: 'lazy'현재 구현 중, 우리는 "로드 지연 모듈"단추를 누르기만 하면 모듈을 불러올 수 있지만, 현재 활성화된 루트에 따라 트리거가 필요합니다.따라서 다음 코드 블록을 ngOnInitAppComponent 방법에 추가해야 합니다.
      ngOnInit(): void {
        this.router.events.subscribe(async routerEvent => {
          if (routerEvent instanceof NavigationStart) {
            if (routerEvent.url.includes('lazy') && !this.isLazyRouteAvailable()) {
              this.loadLazyModule(routerEvent.url);
            }
          }
        });
        this.routes = this.router.config;
      }
    
      private isLazyRouteAvailable(): boolean {
        return this.router.config.filter(c => c.path === 'lazy').length > 0;
      }
    
    각도 라우터의 NavigationStart 이벤트에 가입합니다. URL에 지연 경로가 포함되어 있다면, 라우터 설정에 있는지 확인하십시오. 그렇지 않으면 불러옵니다.
    이제 URL에 책갈피를 추가할 수 있습니다. 응용 프로그램은 루트를 활성화한 후에 모듈을 불러오는 것을 지연합니다.

    각도 구성 요소 수동 로드


    우리는 수동 지연 로드 모듈에서 동적 로드 각도 구성 요소를 더욱 진일보할 수 있다.
    Angular 버전 2~8에서 동적 로드 구성 요소는 상당히 복잡합니다. 이 버전 중 하나의 해결 방안이 필요하면 유행하는 hero-loader package 을 보십시오.Angular 9이 더 쉬우므로 이 과정을 설명해 드리겠습니다.
    LazyModule에는 동적으로 로드된 구성 요소를 표시하는 하위 라우팅과 자리 표시자 구성 요소가 포함되어 있습니다.
    export const LAZY_ROUTES: Routes = [
      {
        path: '',
        component: LazyHomeComponent,
        children: [
          {
            path: 'dynamic-component',
            component: PlaceholderComponent,
          },
        ],
      },
    ];
    
    자리 표시자 구성 요소의 템플릿에는 <ng-template> HTML 태그만 있습니다.
    <ng-template></ng-template>
    
    placeholder.component.ts 에서 현재 DynamicLazyComponent 초기화 후 동적 로드 PlaceholderComponent:
    @Component({
      selector: 'app-placeholder',
      templateUrl: './placeholder.component.html',
      styleUrls: ['./placeholder.component.css'],
    })
    export class PlaceholderComponent implements OnInit {
      @ViewChild(TemplateRef, { read: ViewContainerRef })
      private templateViewContainerRef: ViewContainerRef;
    
      constructor(
        private readonly componentFactoryResolver: ComponentFactoryResolver
      ) {}
    
      async ngOnInit() {
        import('../../dynamic-lazy/dynamic-lazy.component').then(
          ({ DynamicLazyComponent }) => {
            const component = this.componentFactoryResolver.resolveComponentFactory(
              DynamicLazyComponent
            );
            const componentRef = this.templateViewContainerRef.createComponent(
              component
            );
          }
        );
      }
    }
    
    이 코드 블록에 대한 몇 가지 설명:
  • 우리는 @ViewChild() 장식기를 사용하여 TemplateRef 요소의 <ng-template> 실례를 조회한다.
  • @ViewChild() 장식부호({ read: ViewContainerRef }의 두 번째 파라미터는 보기 조회에서 ViewContainerRef 실례를 읽는 데 사용할 수 있습니다.
  • templateViewContainerRef 렌더링 엔진이 로드를 지연시키는 구성 요소를 어디에서 렌더링해야 하는지 알려주는 데 사용됩니다.
  • 우리는 같은 import(...) 문법을 사용하여 구성 요소를 불러오는 것을 지연시킨다. 우리가 모듈에 대해 한 것처럼.
  • Angular 9 때문에 엔트리 구성 요소로 등록하고 추가할 모듈이 없습니다.각도가 8인 구성 요소를 동적으로 로드하려면 보기
    다음 그림은 이 구성 요소의 로드 지연 과정을 보여 줍니다.

    결론


    Angular 9은 실행 시 모듈과 구성 요소를 수동으로 가져올 수 있는 매우 간결하고 우아한 해결 방안을 제공합니다.
    현재, 실행할 때 불러오는 프로필에서 설정할 수 있는 매우 동적인 사용자 인터페이스를 만들 수 있으며, 이 정보를 바탕으로 새로운 루트를 사용하여 서로 다른 모듈과 구성 요소를 불러올 수 있습니다.

    좋은 웹페이지 즐겨찾기