От автора: несколько месяцев назад я опубликовал статью о Guess.js. Guess.js — мощная библиотека для прогнозируемого предварительного извлечения JavaScript на основе данных аналитики веб-сайта. Библиотека использует отчеты из источника аналитики (по умолчанию Google Analytics) и создает базовую модель машинного обучения.
Когда пользователь заходит на сайт, с помощью Guess.js на основе модели происходит предварительная загрузка ресурсов, которые, вероятно, понадобятся дальше. Благодаря подходу, основанному на данных, Guess.js предлагает много преимуществ — уменьшает объем извлекаемых данных, не выполняет агрессивное предварительное извлечение в медленных сетях и т. д.
В этом посте мы рассмотрим другой подход к предварительному извлечению, который использует две эвристики:
Пользователи могут посещать ссылки, которые видны на странице
Мы не хотим агрессивно выполнять предварительное извлечение, если пользователь использует медленный интернет

Бесплатный курс «Laravel + Angular. Быстрый старт»
Изучите курс и узнайте, как создать веб-приложение с нуля на Angular и Laravel
Получить курсМы хотим выполнять предварительное извлечение только тогда, когда браузер простаивает
Предварительное извлечение с помощью quicklink
GatsbyJS — это генератор статических сайтов, который славится производством высокоскоростных прогрессивных веб-приложений. Чтобы стать еще быстрее, Gatsby использует агрессивное предварительное извлечение ссылок.
Когда ссылка видна на экране, Gatsby предварительно извлекает контент, связанный с ней. Это достигается с помощью IntersectionObserver путем сопоставления между ссылкой и связанным ресурсом, который доступен во время сборки.
Потенциальным недостатком этого подхода является чрезмерный объем извлекаемых данных, что может привести к дополнительному использования пропускной способности канала. Другая незначительная проблема связана с переходом на страницы, на которые нет прямых ссылок на странице. Этот сценарий возможен, например, когда пользователь обновляет URL-адрес в адресной строке вручную. Guess.js хорошо справляется с обеими проблемами, и, к счастью, для Gatsby есть плагин Guess.js. Однако для использования Guess.js необходим источник аналитики. Возможный компромисс, для которого не требуется аналитика — это предварительное извлечение ресурсов только тогда, когда пользователь использует быстрый канал связи.
quicklink — это проект, который реализует данный алгоритм! Библиотека предварительно извлекает контент, связанный со всеми ссылками, которые в данный момент видны на странице, в случае, если пользователь работает в быстрой сети. quicklink не выполняет предварительное извлечение, если пользователь работает в сети 2G или медленнее. Для определения сети пользователя Guess.js и quicklink используют navigator.connection.effectiveType.
quicklink в Angular
quicklink — это скрипт, который вы вводите на страницу, и он выполняет свою работу. К сожалению, это не относится к платформам, которые управляют собственной маршрутизацией, создавая косвенное отношение между URL-адресом и контентом. Примерами этого являются Angular, React с React Router и т. д. Давайте рассмотрим пример Angular:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
import { Routes } from "@angular/router"; export const routes: Routes = [{ path: 'about', loadChildren: './about/about.module#AboutModule' }, { path: 'contact', loadChildren: './contact/contact.module#ContactModule' }, { path: '', redirectTo: '', pathMatch: 'full' }]; |
С помощью следующего определения маршрутизации мы можем ссылаться на страницу, которую AboutModule будет отображать с помощью routerLink:
1 |
<a routerLink="/about">About</a> |
quicklink найдет все элементы a на странице во время простоя и предварительно выберет страницу, связанную с их атрибутом href. Принимая во внимание приведенный выше шаблон, это не будет работать, как ожидалось. quicklink не сможет найти пакет, связанный со страницей /about.
Представляем ngx-quicklink
Чтобы позволить всем разработчикам Angular воспользоваться мощной стратегией предварительной выборки, которую предоставляет quicklinkя, я создал ngx-quicklink.
Использование
ngx-quicklink имеет две основные части:
QuicklinkModule — включает в себя несколько внутренних служб и директиву, которая сначала находит все ссылки на маршрутизатор, а затем определяет, когда они видны на экране.
PreloadingStrategy — реализация интерфейса PreloadingStrategy, предоставляемого @angular/router. Он обеспечивает абстракцию для службы, которая решает, должен ли данный маршрут быть предварительно извлечен в данной точке.
Для использования ngx-quicklink сначала убедитесь, что вы установили пакет:
1 |
npm i ngx-quicklink --save |
Вот как вы можете интегрировать его QuicklinkModule с существующим приложением:

Бесплатный курс «Laravel + Angular. Быстрый старт»
Изучите курс и узнайте, как создать веб-приложение с нуля на Angular и Laravel
Получить курс
1 2 3 4 5 6 7 8 9 |
import { QuicklinkModule } from 'ngx-quicklink'; ... @NgModule({ imports: [QuicklinkModule], declarations: [...], exports: [QuicklinkModule] }) export class SharedModule {} |
Фрагмент выше добавляет QuicklinkModule к спискам imports и exports из SharedModule. Этот модуль должен быть позже импортирован в AppModule и все отложено загруженные модули. Вам не нужно создавать новый общий модуль, если он у вас уже есть.
Далее, в модуле маршрутизации установите стратегию предварительной загрузки:
1 2 3 4 5 6 7 8 9 10 |
import { QuicklinkStrategy } from 'ngx-quicklink'; ... @NgModule({ imports: [RouterModule.forRoot(routes, { preloadingStrategy: QuicklinkStrategy })], exports: [RouterModule] }) export class AppRoutingModule {} |
По этой ссылке вы можете узнать, как интегрировать ngx-quicklinkс angular-realworld-example-app.
Как это работает
Вот ключевые особенности ngx-quicklink:
Обнаруживает routerLinks в области просмотра (используя Intersection Observer)
Ожидает, пока браузер не будет в режиме простоя (с помощью requestIdleCallback)
Проверяет, не подключен ли пользователь к медленному соединению (используя navigator.connection.effectiveType) или включен ли режим сохранения данных (используя navigator.connection.saveData)
Предварительно загружает модули с использованием стратегии предварительной выборки Angular)
Существует три основных различия между исходной реализацией quicklink и ngx-quicklink:
quicklink предварительно выбирает ресурсы link[rel=»prefetch»], если они есть, и резервирует их в XMLHttpRequest. ngx-quicklink использует только XMLHttpRequest из-за текущего механизма предварительной загрузки модуля маршрутизатора Angular. Хотя link[rel=»prefetch»] — это лучшая альтернатива, также используемая Guess.js, скорее всего, ваши пользователи не заметят разницы.
ngx-quicklink не только загружает связанные пакеты JavaScript, но также анализирует и оценивает содержимое. Это позволяет еще больше повысить производительность, когда пользователь переходит на другую страницу.
ngx-quicklink загружает все родительские модули запрошенного модуля для предварительного извлечения.
Давайте рассмотрим последний момент. Предположим, у нас есть следующее определение маршрутизации:
1 2 3 4 5 6 |
export const routes: Routes = [{ path: 'about', loadChildren: './about/about.module#AboutModule' }, ... ]; |
В AboutModule у нас есть следующий маршрут:
1 2 3 4 5 6 |
export const routes: Routes = [{ path: 'team', loadChildren: './team/team.module#TeamModule' }, ... ]; |
Если на странице есть routerLink=»/about/team», ngx-quicklink сначала загрузит AboutModule, а после этого TeamModule.
Заключение
В этой статье мы рассмотрели предварительную загрузку в веб-приложениях. Мы обсудили стратегию предварительного извлечения quicklink. После этого мы рассмотрели разницу между предиктивной предварительной выборкой и quicklink.
В следующем разделе мы введем quicklink в контекст Angular и рассмотрим ограничения оригинальной реализации. Объединив директиву Angular routerLink с PreloadingStrategyngx фреймворка, мы представим реализацию ngx-quicklink — quicklink для Angular.
Источник: //blog.mgechev.com/
Редакция: Команда webformyself.

Бесплатный курс «Laravel + Angular. Быстрый старт»
Изучите курс и узнайте, как создать веб-приложение с нуля на Angular и Laravel
Получить курс