Разделяй и властвуй! Отложенная загрузка для вашего SPA

Разделяй и властвуй! Отложенная загрузка для вашего SPA

От автора: «Как же это медленно? Я использую только 100 компонентов. Давай же, браузер, делайте свое дело! »Звучит знакомо? Ну, пришло время попробовать повысить производительность. Если вы являетесь веб-разработчиком, скорее всего, вы используете Webpack, и, возможно, вы не знаете, что такое отложенная загрузка.

Что такое отложенная (ленивая) загрузка?

Я знаю, о чем вы подумали: «Ленивый — это не быстрый, это совершенно противоположно тому, что нужно». Вы не ошибаетесь в семантике, но нужно посмотреть на ситуацию под другим углом. Давайте рассмотрим определение для отложенной загрузки, согласно Webpack:

«Отложенная, или «по требованию», загрузка — отличный способ оптимизировать ваш сайт или приложение. Эта практика по существу включает разделение кода на логические точки остановки, а затем его загрузку после того, как пользователь выполнил что-то, для чего требуется новый блок кода».

Другими словами, вы можете разделить свой код так, как хотите (то есть на компоненты), и браузер загрузит только код, необходимый для работы вашего приложения. Звучит потрясающе!

Зачем мне это нужно?

Это простой вопрос. Чтобы повысить производительность! При отложенной загрузке загружается только нужный код, и при этом ваша первоначальная загрузка будет быстрее (потому что вы загрузите гораздо меньше кода), а ваша общая скорость будет намного выше.

Мне также нравится, как вставляется код при ленивой загрузке. Без этого у вас, вероятно, будет HTML-файл, CSS и только один гигантский JS.

Как я могу это сделать?

Прежде всего, вам понадобится Webpack, а с ним, Babel и несколько плагинов.

npm i -D dynamic-import-webpack syntax-dynamic-import

Теперь, когда мы все подготовили, нам нужно добавить их в .babelrc, наш конфигурационный файл Babel.

{ "plugins": [ ... "dynamic-import-webpack", "syntax-dynamic-import" ], "presets": [ ["env", { "targets": [ "last 2 versions", "safari >= 7", "not ie < 9" ] }] ] }

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

Вероятно, вы думаете, что вам придется изменить код. Правда в том, что этого не требуется. Единственное, что нужно изменить — это то, как вы импортируете код.

Покажи мне код!

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

import React from 'react';
// Мы можем использовать react-loadable, чтобы охватить большинство вариантов вывода разделенного кода
import Loadable from 'react-loadable'; // Компонент загрузчика
import Loader from '@components/Loader'; // Создаем асинхронный маршрут
const AsyncRoute = Loadable({ loader: () => import('./index'), loading() { return <Loader />; }
}); // Это то, что будет использовать компонент React Router
const MyRoute = props => <AsyncRoute {...props} />; export default MyRoute;

Асинхронный маршрут React с использованием react-loadable

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

import Vue from 'vue' import Navbar from '../../components/Navbar' const AsyncComponent = () => import('../../components/AsyncComponent') const vm = new Vue({ el: '#app', // ... все атрибуты необходимые для вашего экземпляра components: { Navbar, AsyncComponent }
})

Асинхронный компонент Vue

Для Vue компонент может быть запрошен с помощью только функции динамического импорта и зарегистрирован в экземпляре, как показано выше. Это только для компонентов, но для маршрутов процедура та же, просто добавьте компонент в качестве компонента маршрута в конфигурацию вашего маршрутизатора.

И, конечно, мы не можем забыть об Angular , поскольку мы можем также сделать это, изменив только конфигурацию:

import { RouterModule, Routes, PreloadAllModules } from @angular/router; // Вы можете указать Angular, что маршрут является асинхронным, с помощью хэша в конце импорта
export const ROUTES: Routes = [ { path: '', pathMatch: 'full', redirectTo: 'dashboard' }, { path: 'dashboard', loadChildren: '../dashboard/dashboard.module#DashboardModule' }, { path: 'settings', loadChildren: '../settings/settings.module#SettingsModule' }, { path: 'reports', loadChildren: '../reports/reports.module#ReportsModule' }
]; @NgModule({ // ... imports: [ RouteModule.forRoot(ROUTES, { preloadingStrategy: PreloadAllModules }) ], // ...
})
export class AppModule {}

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

Приложение React с отложенной загрузкой

Здесь мы отделяем асинхронный маршрут нашего приложения от основного блока кода. Теперь у нас есть фрагменты, как мы хотим, чтобы это работало? Давайте посмотрим на представление «Сеть» в консоли браузера при загрузке представления:

Запросы Chrome к нашим компонентам используются только в этом представлении

Эти пронумерованные JS-файлы являются нашими асинхронными компонентами, загружаемыми только тогда, когда это необходимо. Эти запросы являются компонентами Vue без какого-либо пакета, что работает также, как react-loadable, поэтому они не хешируются, как на изображении выше (последнее из них — приложение React)

Можем ли мы сделать какие-либо выводы? Возможно, если вы не используете асинхронные компоненты, попробуйте их! Конечно, здесь я показал вам, как разделять код на асинхронные маршруты и компоненты, но вы также можете разделить свои файлы по-другому. Таким образом, вы можете свести к минимуму первоначальную загрузку даже большого приложения, а также улучшить другие аспекты производительности.

Автор: Martin Callegari

Источник: https://medium.com/

Редакция: Команда webformyself.