Skip to content

Orchestrate dynamically imported components in Angular applications

License

Notifications You must be signed in to change notification settings

Lotto24/angular

Repository files navigation

@lotto24-angular

imports-orchestrator

This library provides the imports-orchestrator library to control the order in which Angular components and modules are loaded. This can be useful when optimizing page performance in an Application.

Setup

const APP_IMPORTS_ORCHESTRATION = {
  'first': 1,
  'second': 2,
  'third': 3,
};

export type AppImportsOrchestration = typeof APP_IMPORTS_ORCHESTRATION;

export const appConfig = {
  providers: [
    // ...
    provideImportsOrchestration(
      // specify the priority of your imports (queue works from low to high)
      APP_IMPORTS_ORCHESTRATION,
      // routes should be resolved as quickly as possible:
      withSuspendWhileRouting(),
      // automatically adjusts the number of concurrent imports depending on the client's connection:
      withConcurrencyRelativeToDownlinkSpeed(4, 1)
    ),
  ],
};

Usage:

import {AppImportsOrchestration} from "./app.config";

@Component({
  selector: 'example',
  standalone: true,
  changeDetection: ChangeDetectionStrategy.OnPush,
  imports: [ImportsOrchestratorDirective],
  template: `
    <ng-container
      import="second"
      [inputs]="{ text: headline }"
      [outputs]="{ click: onClick }"
    ></ng-container>
    <import 
      identifier="first"
      [inputs]="{ text: description }"
      [outputs]="{ click: onClick }"
    ></import>
  `,
})
// Your dynamic imports can be added with this decorator
@Imports<AppImportsOrchestration>({
  'first': importStandalone(
    () => import('@some/thing')
  ),
  'second': importNgModule(
    () => import('@other/fancy-lib')
  ),
  'third': importPromise(() =>
    fetch('/assets/example.json').then((res) => res.json())
  ),
})
export class ExampleComponent {
  @Input() headline = 'Some catchy title';
  @Input() description = 'Elaborate description';

  private readonly importService = inject(ImportService);

  constructor() {
    this.fetchExample();
  }

  public async fetchExample(): Promise<void> {
    const item = this.importService.createQueueItem('third', NEVER);

    // you can await the item here, but you don't have to
    try {
      const result = await this.importService.addItemToQueue(item);
      console.log('result', result);
    } catch (e) {
      console.error(e);
    }
  }
}

Resolve

  • Standalone components with importStandalone(() => import('path/to/esm')
  • NgModules (with or without bootstrapped components), usingimportNgModule(() => import('path/to/esm').then(m => m.SomeNgModule)
  • Arbitrary promises (eg. fetch) via importPromise(() => fetch('http://some.url/json').then(result => result.json)

Configurable features

Concurrency

  • withConcurrencyStatic(value: number) (default)
  • withConcurrencyRelativeToDownlinkSpeed(max: number = 4, min: number = 1)

Routing

  • withoutRouting() (default, as some apps do not use routing),
  • withSuspendWhileRouting(suspendForInitialNavigation = true), routes should be resolved as fast as possible, so this will cause the queue to suspend processing until routing is finished

Logging

  • withLogger(logger: Console, prefix: string = '[ImportsOrchestrator]') by default Console is used

Timeout

  • withTimeout(timeout: number = 10000) Timeout applies to each item on the queue individually by default, 10000ms are applied

Example application

Please see apps/imports-orchestrator-example/src/app/app.component.ts and apps/imports-orchestrator-example/src/app/home/home.component.ts on how to use.

Warning: API is not stable. Everything is subject to change.

Run nx serve imports-orchestrator-example to explore.

Development server

Run nx serve imports-orchestrator-example for a dev server. Navigate to http://localhost:4200/. The app will automatically reload if you change any of the source files.

Built on Nx

This workspace has been generated by Nx, a Smart, fast and extensible build system. ✨ Visit the Nx Documentation to learn more.

About

Orchestrate dynamically imported components in Angular applications

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages