Рубрики
Без рубрики

Маршруты Lazy-loading с Vue Router с прогрессом

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

Автор оригинала: Guest Contributor.

Вступление

По умолчанию при написании приложения Other Page Vue.js (SPA) все необходимые активы, такие как файлы JavaScript и CSS, загружены вместе, когда страница загружена. При работе с большими файлами это может привести к неудовлетворительному опыту пользователя.

С помощью WebPack , можно загрузить страницы по требованию в Vue.js, используя Импорт () Функция вместо Импорт ключевое слово . Отказ

Зачем нагружать на спрос?

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

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

Vue.js не поставляется с каким-либо индикатором погрузки для динамических модулей. Даже с предварительной выборкой и предварительной нагрузкой – никакого визуального индикатора не позволяет пользователям знать, как идет загрузка. Мы также добавим панель прогресса для улучшения пользовательского опыта.

Подготовка проекта

Сначала нам нужен путь для нашего прогресса, чтобы общаться с Vue Router. Для этого мы будем использовать Шаблон автобуса событий Отказ

Шина событий в основном является экземпляром Singleton Vue. Поскольку все экземпляры Vue имеют систему событий, используя $ на и $ Emit Мы можем использовать его, чтобы пройти события в любом месте в нашем приложении.

Давайте создадим новый файл, eventhub.js В Компоненты Каталог:

import Vue from 'vue'
export default new Vue()

Теперь мы настроим WebPack для отключения предварительной обработки и предварительной загрузки. Мы можем сделать это индивидуально для каждой функции, либо отключить его глобально. Создать vue.config.js Файл в корневой папке и добавьте конфигурацию для отключения предварительной выборки и предварительной нагрузки:

module.exports = {
    chainWebpack: (config) => {
        // Disable prefetching and preloading
        config.plugins.delete('prefetch')
        config.plugins.delete('preload')
    },
}

Добавление маршрутов и страниц

Мы будем использовать Vue Router. На этот цель мы будем использовать NPX Чтобы установить его:

$ npx vue add router

Теперь давайте отредактируем наш файл маршрутизатора, обычно расположен под Маршрутизатор/index.js и обновить наши маршруты для использования Импорт () Функция, а не Импорт утверждение:

Это конфигурация по умолчанию:

import About from '../views/About.vue'
{
    path: '/about',
    name: 'About',
    component: About
},

Мы изменили это на:

{
    path: '/about',
    name: 'About',
    component: () => import('../views/About.vue')
},

Если вы предпочитаете выбрать, какие страницы загружаются по требованию вместо того, чтобы отключить предварительную выборку и предварительную загрузку глобально, используйте специальный веб-пакет комментарии вместо того, чтобы настроить WebPack в vue.config.js :

import(
    /* webpackPrefetch: true */
    /* webpackPreload: true */
    '../views/About.vue'
)

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

Реализация бара прогресса

Так как невозможно точно оценить, когда страница будет загружаться (или если она вообще загрузится), мы не можем Действительно сделать бар прогресс. Там нет способа проверить, сколько загружена страница. Что мы может сделать Создать панель выполнения, которая заканчивается, когда страница нагрузки.

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

Давайте установим Лодаш.Рандом Во-первых, поскольку мы будем использовать этот пакет, чтобы выбрать несколько случайных чисел во время генерации прогресса:

$ npm i lodash.random

Тогда давайте создадим VUE компонент – Компоненты/ProgressBar.Vue :


Теперь, к этому компоненту, мы будем добавлять скрипт. В этом скрипте мы сначала импортируем Случайные и $ EventHub , как мы будем использовать те,


Теперь после импорта в том же скрипте мы можем определить некоторые переменные, которые мы будем использовать:

// Assume that loading will complete under this amount of time.
const defaultDuration = 8000 
// How frequently to update
const defaultInterval = 1000 
// 0 - 1. Add some variation to how much the bar will grow at each interval
const variation = 0.5 
// 0 - 100. Where the progress bar should start from.
const startingPoint = 0 
// Limiting how far the progress bar will get to before loading is complete
const endingPoint = 90 

С теми на месте, давайте напишем логику асинхронно загружать компоненты:

export default {
    name: 'ProgressBar',
    
    data: () => ({
        isLoading: true, // Once loading is done, start fading away
        isVisible: false, // Once animate finish, set display: none
        progress: startingPoint,
        timeoutId: undefined,
    }),

    mounted() {
        $eventHub.$on('asyncComponentLoading', this.start)
        $eventHub.$on('asyncComponentLoaded', this.stop)
    },

    methods: {
        start() {
            this.isLoading = true
            this.isVisible = true
            this.progress = startingPoint
            this.loop()
        },

        loop() {
            if (this.timeoutId) {
                clearTimeout(this.timeoutId)
            }
            if (this.progress >= endingPoint) {
                return
            }
            const size = (endingPoint - startingPoint) / (defaultDuration / defaultInterval)
            const p = Math.round(this.progress + random(size * (1 - variation), size * (1 + variation)))
            this.progress = Math.min(p, endingPoint)
            this.timeoutId = setTimeout(
                this.loop,
                random(defaultInterval * (1 - variation), defaultInterval * (1 + variation))
            )
        },

        stop() {
            this.isLoading = false
            this.progress = 100
            clearTimeout(this.timeoutId)
            const self = this
            setTimeout(() => {
                if (!self.isLoading) {
                    self.isVisible = false
                }
            }, 200)
        },
    },
}

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

И, наконец, давайте добавим немного стиля к нему:


Теперь давайте добавим наше ProgressBar нашему App.vue Или компонент макета до тех пор, пока он находится в том же компоненте, что и вид маршрутизатора. Мы хотим, чтобы это было доступно в течение всего жизненного цикла приложения:




Это все приводит к гладкой баре прогресса, похоже на это:

индикатор

ДРУГОС PROGEL PROGES для ленивых страниц

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

import $eventHub from '../components/eventHub'

router.beforeEach((to, from, next) => {
    if (typeof to.matched[0]?.components.default === 'function') {
        $eventHub.$emit('asyncComponentLoading', to) // Start progress bar
    }
    next()
})

router.beforeResolve((to, from, next) => {
    $eventHub.$emit('asyncComponentLoaded') // Stop progress bar
    next()
})

Чтобы обнаружить, что страница ленивая загружена, нам нужно проверить, определяется ли компонент как динамический импорт I.e. Компонент: () => Импорт («...») вместо Компонент: MyComponent Отказ

Это делается с typeof to.matched [0] ?. ports.default Отказ Компоненты, которые были загружены Импорт Заявление не будет классифицировано как функции.

Заключение

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