Параметры маршрута и ленивая загрузка

Один маршрут product/:id обслуживает тысячи товаров, а ленивая загрузка подгружает код страницы только когда на неё зашли.

«Зачем грузить код админки тому, кто пришёл за одним товаром? Ленивая загрузка приносит код по требованию, а не оптом».

Страницы часто динамические: карточка товара, профиль пользователя — у каждого свой id в URL. Это параметры маршрута, обозначаемые двоеточием:

export const routes: Routes = [
  { path: 'product/:id', component: ProductComponent },
];

В современном Angular параметр можно получить прямо как сигнальный вход — достаточно включить withComponentInputBinding() и объявить input с тем же именем:

@Component({
  selector: 'app-product',
  standalone: true,
  template: `<h2>Товар №{{ id() }}</h2>`,
})
export class ProductComponent {
  id = input.required<string>();   // придёт из :id
}

Второй герой урока — ленивая загрузка. Вместо component используйте loadComponent с динамическим импортом: код страницы скачается только при переходе на неё, уменьшая стартовый бандл.

export const routes: Routes = [
  {
    path: 'admin',
    loadComponent: () =>
      import('./admin/admin.component').then(m => m.AdminComponent),
  },
  {
    path: 'reports',
    loadChildren: () =>
      import('./reports/reports.routes').then(m => m.reportRoutes),
  },
];

Как работает под капотом

Динамический import() возвращает промис, который браузер исполняет только в момент вызова. Сборщик при этом выделяет код страницы в отдельный чанк. Когда пользователь переходит на /admin, роутер вызывает функцию загрузки, браузер скачивает чанк, и лишь затем создаёт компонент. До этого момента код админки вообще не загружен.

   старт приложения  ->  грузим только основной бандл
        |
   переход на /admin
        |
   loadComponent() -> import('./admin...')  (скачивается чанк admin.js)
        |
   чанк загружен -> создать AdminComponent -> в outlet

Частые ошибки

  • Грузить всё через component. Тяжёлые редко используемые разделы стоит делать ленивыми.
  • Несовпадение имени параметра и input. :id в пути и id в компоненте должны совпадать.
  • Забыть withComponentInputBinding() — без него параметры не придут как input.

Best practices

  • Делайте ленивыми крупные функциональные области (админка, отчёты, личный кабинет).
  • Читайте параметры через input-привязку — это чище, чем ручная подписка на ActivatedRoute.
  • Группируйте дочерние маршруты в отдельные файлы и подключайте через loadChildren.

Итоги. Параметры :id делают маршруты динамическими и читаются как input-сигналы; loadComponent/loadChildren грузят код по требованию, ускоряя старт. Дальше — формы для ввода данных.

Закрепляем

Параметры маршрута превращают один шаблон пути в бесконечное число конкретных страниц. Путь product/:id обслуживает и товар №7, и товар №999 — двоеточие помечает динамическую часть. В современном Angular эти параметры удобнее всего получать как сигнальные входы: при включённом withComponentInputBinding() параметр :id сам попадает в одноимённый input компонента, без ручной подписки на ActivatedRoute.

Вторая идея урока — ленивая загрузка, и она напрямую влияет на скорость старта. Нет смысла грузить код раздела админки тому, кто зашёл посмотреть один товар. Конструкции loadComponent и loadChildren с динамическим import() заставляют сборщик выделить код раздела в отдельный чанк, который скачивается только при переходе на соответствующий маршрут. В результате стартовый бандл остаётся лёгким, а тяжёлые редко используемые области приходят по требованию. Делайте ленивыми крупные функциональные блоки — это один из самых дешёвых способов ускорить приложение.

КонструкцияНазначение
path: 'product/:id'Динамический параметр
withComponentInputBinding()Параметр как input
loadComponentЛенивый компонент
loadChildrenЛенивая группа маршрутов
Проверьте себя
1. Что делает loadComponent с динамическим import()?
AЗагружает компонент сразу при старте
BОткладывает загрузку кода страницы до момента перехода на маршрут (lazy loading)
CУдаляет компонент из бандла
DСоздаёт копию компонента
2. Как современно прочитать параметр :id из маршрута?
AТолько через document.location
BОбъявить input с именем id при включённом withComponentInputBinding()
CЧерез глобальную переменную
DПараметры читать нельзя