Spec-Zone.ru › Angular

Ленивая загрузка сервисов

ВАЖНО: Для работы ленивой загрузки сервис должен предоставляться автоматически. Декорируйте его с помощью @Injectable({providedIn: 'root'}) или @Service(). Без автоматического предоставления Angular не сможет создать сервис после его загрузки.

Функция injectAsync в Angular позволяет загружать сервис по запросу, только когда он действительно нужен. Это полезно, если сервис зависит от большой библиотеки или редко используемой функции и вы не хотите платить за её загрузку при первоначальной загрузке страницы.

При использовании injectAsync ваш сборщик выносит код сервиса в отдельный фрагмент JavaScript, который загружается при первом запросе экземпляра. После загрузки Angular разрешает сервис через обычную систему DI, поэтому он по-прежнему может зависеть от других внедряемых зависимостей и ведёт себя как любой другой синглтон.

Ленивое внедрение сервиса

Представьте ReportExporter, который зависит от тяжёлой библиотеки для работы с электронными таблицами. Большинство пользователей открывают отчёт, и лишь немногие нажимают Экспорт. Загружайте модуль экспорта по запросу:

import {Component, injectAsync} from '@angular/core';

@Component({
  selector: 'app-report',
  template: `<button (click)="export()">Export</button>`,
})
export class Report {
  private exporter = injectAsync(() => import('./report-exporter').then((m) => m.ReportExporter));

  async export() {
    const exporter = await this.exporter();
    exporter.export();
  }
}

Первый вызов this.exporter() запускает динамический импорт и разрешает сервис из DI. Последующие вызовы используют тот же промис, поэтому фрагмент загружается только один раз.

Если лениво загружаемый сервис экспортируется по умолчанию, передайте динамический импорт напрямую, и Angular извлечёт default за вас:

@Service()
export default class ReportExporter {
  /* … */
}
private exporter = injectAsync(() => import('./report-exporter'));

Предварительная загрузка зависимости

По умолчанию ленивый фрагмент загружается только при вызове возвращённой функции. Вы можете начать загрузку раньше, передав в параметрах prefetch триггер. Триггер — это любая функция, возвращающая Promise; когда он разрешается, Angular запускает загрузчик.

В Angular есть встроенный триггер onIdle, который ожидает, пока браузер перейдёт в режим ожидания:

import {Component, injectAsync, onIdle} from '@angular/core';

@Component({
  /* … */
})
export class Report {
  private exporter = injectAsync(() => import('./report-exporter').then((m) => m.ReportExporter), {
    prefetch: onIdle,
  });
}

Вы также можете настроить onIdle, указав максимальное время ожидания, чтобы предварительная загрузка всегда выполнялась в пределах заданного интервала, даже на загруженных страницах:

injectAsync(loader, {prefetch: () => onIdle({timeout: 1_000})});

ПРИМЕЧАНИЕ: Предварительная загрузка выполняется при наличии возможности. Если пользователь вызовет функцию до запуска предварительной загрузки, Angular всё равно немедленно загрузит зависимость и разрешит ваш await, как только она будет готова.

Настройка собственного триггера предварительной загрузки

PrefetchTrigger — это просто функция, возвращающая промис; загрузчик запускается сразу после его разрешения. Используйте её, чтобы согласовать предварительную загрузку с собственными сигналами, например наведением курсора или тактом планировщика:

import {PrefetchTrigger} from '@angular/core';

export function onHover(target: HTMLElement): PrefetchTrigger {
  return () =>
    new Promise<void>((resolve) => {
      target.addEventListener('pointerenter', () => resolve(), {once: true});
    });
}

Super-powered by Google ©2010–2025.
Code licensed under an MIT-style License. Documentation licensed under CC BY 4.0.
https://angular.dev/guide/di/lazy-loading-services

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API