Spec-Zone.ru › Angular

Инкрементальная гидратация

Инкрементальная гидратация — это расширенный тип гидратации, который позволяет оставлять разделы приложения дегидратированными и постепенно запускать их гидратацию по мере необходимости.

Зачем нужна инкрементальная гидратация?

Инкрементальная гидратация повышает производительность и дополняет полную гидратацию приложения. Она позволяет уменьшить начальные пакеты, сохраняя при этом удобство работы для конечного пользователя на уровне, сопоставимом с полной гидратацией приложения. Уменьшение пакетов ускоряет первоначальную загрузку, снижая показатели задержки первого ввода (FID) и совокупного сдвига макета (CLS).

Инкрементальная гидратация также позволяет использовать отложенные представления (@defer) для содержимого, которое раньше нельзя было откладывать. В частности, теперь отложенные представления можно использовать для содержимого, расположенного выше сгиба. До появления инкрементальной гидратации размещение блока @defer выше сгиба приводило к отображению содержимого-заполнителя, которое затем заменялось основным содержимым шаблона блока @defer. Это приводило к сдвигу макета. Благодаря инкрементальной гидратации основной шаблон блока @defer отображается без сдвига макета при гидратации.

Как включить инкрементальную гидратацию в Angular?

Инкрементальную гидратацию можно включить в приложениях, которые уже используют рендеринг на стороне сервера (SSR) с гидратацией. Сначала следуйте указаниям руководства по SSR в Angular, чтобы включить рендеринг на стороне сервера, а затем указаниям руководства по гидратации в Angular, чтобы включить гидратацию.

Инкрементальная гидратация включена по умолчанию при использовании provideClientHydration().

import {bootstrapApplication, provideClientHydration} from '@angular/platform-browser';

bootstrapApplication(App, {
  providers: [provideClientHydration()],
});

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

Чтобы отказаться от инкрементальной гидратации, используйте withNoIncrementalHydration():

import {
  bootstrapApplication,
  provideClientHydration,
  withNoIncrementalHydration,
} from '@angular/platform-browser';

bootstrapApplication(App, {
  providers: [provideClientHydration(withNoIncrementalHydration())],
});

Как работает инкрементальная гидратация?

Инкрементальная гидратация дополняет полную гидратацию приложения, отложенные представления и повторное воспроизведение событий. При инкрементальной гидратации к блокам @defer можно добавлять дополнительные триггеры, задающие границы инкрементальной гидратации. Добавление триггера hydrate к блоку defer сообщает Angular, что зависимости этого блока нужно загрузить во время рендеринга на стороне сервера и отобразить основной шаблон вместо @placeholder. При рендеринге на стороне клиента зависимости по-прежнему откладываются, а содержимое блока defer остается дегидратированным, пока не сработает его триггер hydrate. Этот триггер сообщает блоку defer, что нужно загрузить зависимости и гидратировать содержимое. Любые события браузера, в частности события, соответствующие обработчикам, зарегистрированным в компоненте, которые пользователь вызывает до гидратации, ставятся в очередь и воспроизводятся после завершения процесса гидратации.

Управление гидратацией содержимого с помощью триггеров

Можно указать триггеры гидратации, которые определяют, когда Angular загружает и гидратирует отложенное содержимое. Это дополнительные триггеры, которые можно использовать вместе с обычными триггерами @defer.

Для каждого блока @defer можно указать несколько триггеров событий гидратации, разделив их точкой с запятой (;). Angular запускает гидратацию при срабатывании любого из триггеров.

Существует три типа триггеров гидратации: hydrate on, hydrate when и hydrate never.

гидратация при

hydrate on задает условие, при котором запускается гидратация блока @defer.

Доступны следующие триггеры:

Триггер Описание
hydrate on idle Срабатывает, когда браузер простаивает. Поддерживает необязательный интервал ожидания.
hydrate on viewport Срабатывает, когда указанное содержимое попадает в область просмотра
hydrate on interaction Срабатывает, когда пользователь взаимодействует с указанным элементом
hydrate on hover Срабатывает, когда указатель мыши наводится на указанную область
hydrate on immediate Срабатывает сразу после завершения рендеринга содержимого, не являющегося отложенным
hydrate on timer Срабатывает по истечении заданного времени

гидратация при простое

Триггер hydrate on idle загружает зависимости отложенного представления и гидратирует содержимое, когда браузер переходит в состояние простоя, согласно requestIdleCallback.

При желании можно указать интервал ожидания в миллисекундах, который передается в requestIdleCallback. Если браузер не запланирует обратный вызов достаточно быстро, операция будет выполнена не позднее указанного времени ожидания.

@defer (hydrate on idle) {
  <large-cmp />
} @placeholder {
  <div>Large component placeholder</div>
}

<!-- With a 500ms timeout -->
@defer (hydrate on idle(500)) {
  <large-cmp />
}

гидратация при попадании в область просмотра

Триггер hydrate on viewport загружает зависимости отложенного представления и гидратирует соответствующую страницу приложения, когда указанное содержимое попадает в область просмотра. Для этого используется API Intersection Observer.

@defer (hydrate on viewport) {
  <large-cmp />
} @placeholder {
  <div>Large component placeholder</div>
}

гидратация при взаимодействии

Триггер hydrate on interaction загружает зависимости отложенного представления и гидратирует содержимое, когда пользователь взаимодействует с указанным элементом посредством событий click или keydown.

@defer (hydrate on interaction) {
  <large-cmp />
} @placeholder {
  <div>Large component placeholder</div>
}

гидратация при наведении

Триггер hydrate on hover загружает зависимости отложенного представления и гидратирует содержимое, когда указатель мыши наводится на указанную область, вызывая события mouseover и focusin.

@defer (hydrate on hover) {
  <large-cmp />
} @placeholder {
  <div>Large component placeholder</div>
}

немедленная гидратация

Триггер hydrate on immediate загружает зависимости отложенного представления и сразу гидратирует содержимое. Это означает, что отложенный блок загружается сразу после завершения рендеринга всего остального содержимого, не являющегося отложенным.

@defer (hydrate on immediate) {
  <large-cmp />
} @placeholder {
  <div>Large component placeholder</div>
}

гидратация по таймеру

Триггер hydrate on timer загружает зависимости отложенного представления и гидратирует содержимое по истечении заданного времени.

@defer (hydrate on timer(500ms)) {
  <large-cmp />
} @placeholder {
  <div>Large component placeholder</div>
}

Параметр длительности необходимо указывать в миллисекундах (ms) или секундах (s).

гидратация при выполнении условия

Триггер hydrate when принимает пользовательское условное выражение, загружает зависимости отложенного представления и гидратирует содержимое, когда условие становится истинным.

@defer (hydrate when condition) {
  <large-cmp />
} @placeholder {
  <div>Large component placeholder</div>
}

ПРИМЕЧАНИЕ: Условия hydrate when срабатывают, только если они относятся к самому верхнему дегидратированному блоку @defer. Условие для триггера задается в родительском компоненте, который должен существовать до того, как триггер сможет сработать. Если родительский блок дегидратирован, Angular пока не сможет вычислить это выражение.

никогда не гидратировать

Триггер hydrate never позволяет указать, что содержимое блока defer должно оставаться дегидратированным неопределенно долго, фактически становясь статическим содержимым. Обратите внимание: это относится только к первоначальному рендерингу. При последующем рендеринге на стороне клиента блок @defer с hydrate never все равно будет загружать зависимости, поскольку гидратация применяется только при первоначальной загрузке содержимого, отрендеренного на стороне сервера. В приведенном ниже примере при последующих рендерингах на стороне клиента зависимости блока @defer будут загружены при попадании в область просмотра.

@defer (on viewport; hydrate never) {
  <large-cmp />
} @placeholder {
  <div>Large component placeholder</div>
}

ПРИМЕЧАНИЕ: Использование hydrate never предотвращает гидратацию всего вложенного поддерева заданного блока @defer. Для содержимого, вложенного в этот блок, другие триггеры hydrate не срабатывают.

Триггеры гидратации вместе с обычными триггерами

Триггеры гидратации — это дополнительные триггеры, которые используются вместе с обычными триггерами блока @defer. Гидратация оптимизирует первоначальную загрузку, поэтому триггеры гидратации применяются только при этой загрузке. При последующих рендерингах на стороне клиента по-прежнему используется обычный триггер.

@defer (on idle; hydrate on interaction) {
  <example-cmp />
} @placeholder {
  <div>Example Placeholder</div>
}

В этом примере при первоначальной загрузке применяется hydrate on interaction. Гидратация запускается при взаимодействии с компонентом <example-cmp />. При любой последующей загрузке страницы с рендерингом на стороне клиента, например когда пользователь нажимает routerLink, который загружает страницу с этим компонентом, применяется on idle.

Как работает инкрементальная гидратация во вложенных блоках @defer?

Система компонентов и зависимостей Angular имеет иерархическую структуру, поэтому для гидратации любого компонента необходимо также гидратировать всех его родителей. Таким образом, если гидратация запускается для дочернего блока @defer во вложенном наборе дегидратированных блоков @defer, она запускается от самого верхнего дегидратированного блока @defer до указанного дочернего блока именно в таком порядке.

@defer (hydrate on interaction) {
  <parent-block-cmp />
  @defer (hydrate on hover) {
    <child-block-cmp />
  } @placeholder {
    <div>Child placeholder</div>
  }
} @placeholder {
  <div>Parent Placeholder</div>
}

В приведенном выше примере наведение указателя на вложенный блок @defer запускает гидратацию. Сначала гидратируется родительский блок @defer с триггером <parent-block-cmp />, затем дочерний блок @defer с <child-block-cmp />.

Ограничения

На инкрементальную гидратацию распространяются те же ограничения, что и на полную гидратацию приложения, в том числе ограничения на прямое управление DOM и требования к корректной структуре HTML. Подробнее см. раздел «Ограничения» руководства по гидратации.

Нужно ли по-прежнему указывать блоки @placeholder?

Да. Содержимое блока @placeholder не используется при инкрементальной гидратации, однако @placeholder по-прежнему необходим для последующего рендеринга на стороне клиента. Если содержимое не находилось на маршруте, загруженном изначально, то при переходе на маршрут с содержимым блока @defer оно отображается как обычный блок @defer. Поэтому в таких случаях рендеринга на стороне клиента отображается @placeholder.

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

Spec-Zone.ru

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