компилируется...
Перейти к основному содержанию
Рекомендовать во Вконтакте Рекомендовать в Фейсбуке Рекомендовать в Твиттере

Как правильно реализовать ленивую загрузку модулей в Angular 8

Angular - отличный javascript фреймворк. Он предоставляет пользователям множество опций, и пользователю остается только решать, как ими воспользоваться. В отличие от React, фреймворк Angular предоставляет множество функций из коробки, таких как маршрутизация. Итак, сегодня я собираюсь написать об одной очень распространенной теме в Angular под названием "Ленивая загрузка".

Что такое Ленивая загрузка?

Ленивая загрузка - это техника, при которой вы загружаете часть веб-страницы в более поздний момент времени, когда эта часть действительно необходима. Но зачем кто-то это делает? Angular - это SPA (Одностраничное приложение), означающее, что оно имеет только одну страницу….все остальное содержимое в DOM и отображается с помощью JavaScript.

Если ваше приложение довольно большое, и у вас весь Javascript сожержится в одном файле (бандле), то ваше приложение, вероятно, будет долго загружаться, когда оно будет в продакшене. И это причина по которой вам нужна ленивая загрузка. Вам следует разделить приложение на более мелкие пакеты, а затем загружать эти пакеты, когда это необходимо.

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

В Angular вам не нужно прилагать особых усилий для реализации Lazy load. Все доступно из коробки. Реализовать ленивую загрузку в Angular намного проще, чем вы думаете. Я постараюсь рассказать о том, как я на самом деле узнал о ленивой загрузке и начал использовать ее во всех проектах, над которыми я работаю.

По умолчанию все модули в Angular будут объединеняются в один основной файл JavaScript. Поэтому, когда вы открываете приложение, оно должно получить этот файл main.js с сервера. Интернет не всегда надежен или скорость интернет соеденения может быть недостаточной, например мобильный интернет. Поэтому, учитывая все эти факторы, если ваш основной файл больше 1 МБ, может потребоваться большое время для загрузки скрипта.

Все это время, пока бандл не будет загружен и обработан, веб-приложение не покажет ничего, кроме пустого белого экрана. Это не очень удобно для пользователя. Когда речь заходит о веб-сайтах или веб-приложениях, время, затрачиваемое на показ исходного контента, очень важно. Поэтому улучшение пользовательского опыта за счет загрузки только нужного участка кода - хорошая идея. Когда пользователь хочет перейти на новую страницу, JavaScript, связан с этой конкретной страницей, может быть отдельно загружен с сервера.

Как сделать ленивую загрузку в Angular 8

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

Мы можем использовать Angular CLI для создания функциональных модулей с маршрутизацией. Итак, давайте сначала рассмотрим обычный способ реализации новой страницы в Angular приложении.

Пример приложения

Для целей данного руководства я использую Angular 8, так как на момент написания статьи это стабильный релиз.

Для целей данного руководства я использую Angular 8, так как на момент написания статьи это стабильный релиз. Есть одно взломное изменение в том, как мы осуществляем ленивую загрузку. Я позабочусь, чтобы и об этой части тоже.

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

  • Главная страница
  • Страница c фильмами
  • Страница с сериями
  • Страница с музыкой

Вариант без ленивой загрузки

Обычный подход, согласно которому те кто не знаком с концепцией ленивой загрузки, будут следовать следующему шаблону: они создают 3 новых компонента, по одному для каждой из страниц, а Главная страница страница является базовой страницей.

1. Сгенерировать приложение с помощью angular cli.

Итак, первое, что нужно сделать, это сгенерировать новое приложение, используя angular cli:

ng new lazy-loading --routing

2. Генерация требуемых компонентов

После этого мы можем начать с создания компонентов для страниц (перейдите в проект lazy-loading):

ng g c pages/home
ng g c pages/movies
ng g c pages/series
ng g c pages/music

Теперь у нас есть главный компонент приложения App, который будет главной страницей, так же у нас есть 3 страницы, которые будут связаны ссылками в заголовке главной страницы.

3. Конфигурация маршрутов

Следующее, что мы сделаем, это добавим маршруты, чтобы мы могли переходить на эти страницы в меню. Для этого добавляем маршруты в файл app-routing.module.ts следующим образом:

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { HomeComponent } from './pages/home/home.component';
import { MoviesComponent } from './pages/movies/movies.component';
import { SeriesComponent } from './pages/series/series.component';
import { MusicComponent } from './pages/music/music.component';

const routes: Routes = [
  {
    path: 'home',
    component: HomeComponent,
  },
  {
    path: 'movies',
    component: MoviesComponent,
  },
  {
    path: 'series',
    component: SeriesComponent,
  },
  {
    path: 'music',
    component: MusicComponent,
  },
  { path: '', redirectTo: 'home', pathMatch: 'full' }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

Замените содержимое app.component.html:

<ul>
  <li>
    <a routerLink="/">Главная</a>
  </li>
  <li>
    <a routerLink="/movies">Видео</a>
  </li>
  <li>
    <a routerLink="/series">Серии</a>
  </li>
  <li>
    <a routerLink="/music">Музыка</a>
  </li>
</ul>

<router-outlet></router-outlet>

После того, как мы запуcтим приложение (npm run start), мы увидим, что приложение теперь может переходить на эти страницы, когда мы нажимаем на соотвествующие ссылки.

Теперь давайте соберём приложение и посмотрим выходные файлы, которые генерируются CLI. Для этого мы используем следующую команду:

ng build --prod

После завершения процесса сборки мы видим, что сгенерированные файлы содержат файл main.js. Этот файл содержит все компоненты, которые мы создали.

Проблема

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

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

Решение

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

Реализация ленивой загрузки в Angular 8

Angular 8 фактически внес некоторые радикальные изменения в то, как мы осуществляем ленивую загрузку в приложениях Angular. В Angular 8 разработчики добавили новый синтаксис для ленивого импорта модулей в приложение.

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

1. Сгенерируйте приложение, используя CLI.

Итак, первое, что нужно сделать, это сгенерировать новое приложение, используя angular CLI:

ng new lazy-loading --routing

2. Сформируйте необходимые компоненты с модулями и маршрутизацией.

Новинкой в Angular 8 является то, что теперь мы можем создать модуль с модулем маршрутизации и компонентом - и все это с помощью одной команды. В отличие от Angular 7, нам нужно было сначала создать модуль с маршрутизацией, а затем создать сам компонент.

Команда выглядит так:

ng g m <module_name> --route <route_name> --module <feature_module_part_of_which_module>

Генерация модуля главной страницы, маршрутизации и компонента:

ng g m pages/home --route home --module app.module

Генерация модуля для страницы с видео, маршрутизация и компонент:

ng g m pages/movies --route movies --module app.module

Генерация модуля для страницы с сериями, маршрутизация и компонент:

ng g m pages/series --route series --module app.module

Генерация модуля для страницы с музыкой, маршрутизация и компонент:

ng g m pages/music --route music --module app.module

Теперь, если вы посмотрите на основной файл app-routing.module.ts, вы увидите что-то вроде того, что показано ниже. Angular CLI автоматически добавляет функциональные модули, которые будут лениво загружаться в модуль маршрутизации приложения.

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

const routes: Routes = [
  { path: 'home', loadChildren: () => import('./pages/home/home.module').then(m => m.HomeModule) },
  { path: 'movies', loadChildren: () => import('./pages/movies/movies.module').then(m => m.MoviesModule) },
  { path: 'series', loadChildren: () => import('./pages/series/series.module').then(m => m.SeriesModule) },
  { path: 'music', loadChildren: () => import('./pages/music/music.module').then(m => m.MusicModule) },
  { path: '', redirectTo: 'home', pathMatch: 'full' }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

Также в файле маршрутизации функционального модуля вы видите, что был добавлен маршрут, давайте возьмем файл movies-routing.module.ts:

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

import { MoviesComponent } from './movies.component';

const routes: Routes = [{ path: '', component: MoviesComponent }];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})
export class MoviesRoutingModule { }

Так же будут добавлены маршруты в модули серий и музыки. Теперь, если вы соберете приложение и пройдётесь по маршрутам, вы увидите, что модули будут загружены отдельно.

Что меняется в ленивой загрузке

Если вы видите файл app-routing.module.ts без ленивой загрузки, то import загружал сразу все компоненты:

import { MoviesComponent } from './pages/movies/movies.component';
import { SeriesComponent } from './pages/series/series.component';
import { MusicComponent } from './pages/music/music.component';

Тут мы импортируем все компоненты в основной файл приложения. В приложении с ленивой загрузкой вам не надо делать импорт компонентов (они уже импортированы в модулях), вместо этого мы указываем загрузку модуля в роутинге с помощью loadChildren. Это означает, что JavaScript этого модуля, не будет входить в основной пакет, а будет находиться в отдельном файле.

Теперь давайте построим приложение и посмотрим выходные файлы, которые генерируются CLI. Для этого мы используем следующую команду:

ng build --prod

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

Эти дополнительные js файлы представляют собой JavaScript для модулей, которые будут загружены при посещении маршрута.

Ленивая загрузка в действии

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

Без ленивой загрузки

Как видите в панели Network (Сеть) при загрузке приложения загружается файл main.js. Когда вы переходите кпо другим ссылкам, не делается никаких других сетевых запросов , так как все идет в комплекте с основным пакетом.

С ленивой загрузкой

При ленивой загрузке, начальная загрузка происходит с файлом main.js и pages-home-home-module.js это главная страница, затем нажимая другие ссылки мы видим что происходит отдельная загрузка каждого модуля.

Разница в скорости загрузки и размере файлов в данном примере довольно таки маленькая, но в большом приложении размер будет увеличиваться в геометрической прогрессии. В случае ленивой загрузки, будут загружены только необходимые файлы соотвествующие маршруту.

Итог

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

Комментарии

Пока что нет комментариев, вы можете быть первым.
Войти или Регистрация , чтобы оставлять комментарии.

Лучшие публикации

Популярные теги

Наш сайт использует куки. Узнайте больше о нашем использовании куки: политика в отношении файлов cookie
Наш сайт существует только благодаря показу онлайн-рекламы нашим посетителям.
Пожалуйста, поддержите нас, отключив блокировку рекламы.