В предыдущей статье мы узнали, что такое разбиение кода, как оно работает с Webpack и как его использовать с отложенной загрузкой в приложении Vue. Теперь мы немного углубимся в код и изучим наиболее полезные шаблоны для разбиения кода в приложениях Vue.js.
Часть 1 — Введение в оптимизацию производительности и отложенную загрузку.
Часть 2 — Отложенная загрузка маршрутов и анти-паттерн использования vendors.js.
Часть 3 — Отложенная загрузка Vuex и отдельных компонент
Часть 4 — Отложенная загрузка библиотек
Часть 5 — Использования кеша Service Worker
Часть 6 — Предзагрузка
Vue-router — это библиотека, которая позволяет разделить веб-приложение на отдельные страницы. Каждая страница представляет собой маршрут, связанный с определенным URL
Зная это, представьте, что у нас есть простое приложение для портфолио со следующей структурой:
Как вы, вероятно, заметили, в зависимости от того, какой маршрут мы посещаем, нам может не понадобиться ни Home.vue, ни About.vue (у которой есть зависимость от lodash). Но тем не менее оба они будут находиться в одном пакете app.js и будут загружаться независимо от того, какой у пользователя будет маршрут посещения. Какая трата времени на загрузку страницы!
Это не имеет большого значения, если у вас маленькое приложение, но представьте, что приложение будет становится все больше и больше, и любое новое дополнение будет означать загрузку большего пакета при первом посещении.
Это недопустимо, когда пользователю достаточно всего 2 — 5 секунд ожидания загрузки что бы покинуть ваш веб-сайт!
Чтобы не ухудшать наше приложение при наращивание функционала, нам просто нужно создать отдельные пакеты для каждого маршрута, используя синтаксис динамического импорта, который мы изучили в предыдущей статье.
Как и все остальное в Vue.js — это чрезвычайно просто. Вместо того, чтобы импортировать компоненты непосредственно в объекты маршрута, нам просто нужно передать туда динамическую функцию импорта. Компонент маршрута будет загружен ТОЛЬКО после задействование данного маршрута.
Таким образом, вместо обычного статического импорта компонента маршрута:
import RouteComponent form './RouteComponent.vue' const routes = [{ path: /foo', component: RouteComponent }]
Нам нужно импортировать его динамически, что создаст новый пакет с этим маршрутом в качестве точки входа:
const routes = [ { path: /foo', component: () => import('./RouteComponent.vue') } ]
Давайте посмотрим, как теперь будут выглядеть наши пакеты и маршрутизация с динамическим импортом:
С помощью этой настройки webpack создаст три пакета:
app.js
—наш основной пакет с точкой входа приложения (main.js) и библиотеками/компонентами, необходимыми для каждого маршрутаhome.js
— комплект с домашней страницей, которая будет загружаться только при использование маршрута /about.js
— пакет с информацией о странице (и ее зависимостью — lodash), которая будет загружена только при использование маршрута /about.*Имена пакетов не являются такими которые сгенерирует webpack. Имена выбраны такими только для облегчения понимания. Webapck генерирует что-то вроде 0.js 1.js и т. д. В зависимости от конфигурации вашего веб-пакета.
Разделение кода на основе маршрутов во многих случаях может решить все проблемы связанные с производительностью и может быть применено практически к любому приложению менее чем за несколько минут!
Возможно вы, используете Nuxt или vue-cli для создания своего приложения. Если это так, важно знать, что у них есть свои нюансы поведение в отношении разделения кода:
Теперь давайте взглянем на очень популярный и часто используемый анти-шаблон, который может сделать воздействие разделения кода на основе маршрутов менее полезным.
Пакет vendor.js обычно используется в виде отдельного js-файла, содержащего все модули из node_modules.
Хотя может показаться заманчивым поместить все зависимые библиотеки в один файл, чтобы иметь возможность кэшировать их, этот подход представляет ту же проблему, что при объединении всех маршрутов:
Видно проблему? Даже если нам нужен lodash (который является одной из зависимостей) только в одном маршруте, он включен в vendor.js вместе со всеми другими зависимостями, и поэтому он всегда будет загружен.
Объединение всех зависимостей в одном файле звучит заманчиво, но это увеличивает время загрузки приложения.
Для того чтобы быть уверенным в том, что будет загружен только необходимый код, можно разделить зависимости по модулям на основе маршрутов. Но это приведет к некоторому дублированию кода.
Предположим, Home.vue также нуждается в lodash.
В этом случае переход от /about (About.vue) к / (Home.vue) приведет к загрузке lodash дважды.
Это все же лучше, чем загружать тонны избыточного кода, но если у нас уже есть эта зависимость, бессмысленно ее не использовать, верно?
В этом нам может помочь webpack плагин splitChunksPlugin
. Просто добавив эти несколько строк в конфигурацию веб-пакета, мы сгруппируем общие зависимости в отдельный пакет, чтобы их можно было использовать совместно.
// webpack.config.js optimization: { splitChunks: { chunks: 'all' } }
В свойстве chunks мы просто сообщаем webpack, какие куски кода следует оптимизировать. Установка этого свойства для всех, как вы, вероятно, догадались, означает, что оно должно оптимизировать их все.
Вы можете прочитать больше об этом процессе в документации по Webpack.
Разделение кода по маршрутам — один из лучших (и самых простых) способов сохранять размер первоночально загружаемого пакета небольшим. В следующей части мы узнаем обо всех других частях (хранилищах Vuex и отдельных компонентах), которые можно отделить от основного пакета и загружать отложено.
Оригинал: Vue.js App Performance Optimization: part 2— Lazy loading routes and vendor bundle anti-pattern.
Краткий перевод: https://vuejs.org/guide/components/v-model.html Основное использование v-model используется для реализации двусторонней привязки в компоненте. Начиная с Vue…
Сегодня мы рады объявить о выпуске Vue 3.4 «🏀 Slam Dunk»! Этот выпуск включает в…
Vue.js — это универсальный и адаптируемый фреймворк. Благодаря своей отличительной архитектуре и системе реактивности Vue…
Недавно, у меня истек сертификат и пришлось заказывать новый и затем устанавливать на хостинг с…
Каким бы ни было ваше мнение о JavaScript, но всем известно, что работа с датами…
Все, кто следит за последними событиями в мире адаптивного дизайна, согласятся, что введение контейнерных запросов…