1. Введение

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

2. Уменьшение размера бандла

Оптимизация импорта:

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

Пример:

// Плохо
import _ from 'lodash';

// Хорошо
    import debounce from 'lodash/debounce';

Использование Tree Shaking:

  • Tree Shaking — это процесс удаления неиспользуемого кода из окончательного бандла. Чтобы использовать Tree Shaking, убедитесь, что ваш проект использует модульную систему ES6.

  • Инструменты, такие как Vite поддерживают Tree Shaking. Важно правильно настроить конфигурацию для максимального эффекта.

Минификация и сжатие:

  • Минификация — это процесс удаления лишних символов из кода (пробелы, комментарии), что уменьшает размер файла. Это можно сделать с помощью Vite (по умолчанию)

  • Сжатие файлов (например, Gzip или Brotli) помогает уменьшить размер передаваемых файлов. Включите сжатие на сервере или используйте плагины для автоматического создания сжатых версий файлов.

3. Lazy Loading компонентов

Что такое Lazy Loading:

  • Lazy Loading (ленивая загрузка) позволяет загружать компоненты или модули только тогда, когда они реально нужны, что уменьшает размер начального бандла и ускоряет загрузку страницы.

Примеры использования:

  • В Vue.js для Lazy Loading компонентов можно использовать динамические импорты и асинхронные компоненты:

import { defineAsyncComponent } from 'vue'

const AsyncComp = defineAsyncComponent(() =>
  import('./components/MyComponent.vue')
)
  • Применение этой техники особенно полезно для маршрутизации, где компоненты загружаются только при переходе на соответствующий маршрут:

// replace
// import UserDetails from './views/UserDetails'
// with
const UserDetails = () => import('./views/UserDetails.vue')

const router = createRouter({
  // ...
  routes: [
    { path: '/users/:id', component: UserDetails }
    // or use it directly in the route definition
    { path: '/users/:id', component: () => import('./views/UserDetails.vue') },
  ],
})

4. Оптимизация рендеринга

Избегание лишних рендеров:

  • При разработке компонентов старайтесь избегать лишних перерисовок. Например, используйте директивы v-if и v-show для управления отображением компонентов:

<div v-if="isVisible">This will only render if isVisible is true</div>

Debouncing и Throttling:

  • Для событий, которые могут часто повторяться (например, ввод текста), используйте технику debouncing, чтобы уменьшить количество вызовов функции:

    import debounce from 'lodash/debounce';
    
    const searchQuery = ref('');
    
    const onInput =  debounce(function (event) {
      searchQuery.value = event.target.value;
    }, 300)

Использование keep-alive:

  • Компонент <KeepAlive/> позволяет сохранять состояние компонентов между их монтированием и размонтированием:

    <KeepAlive>
      <Component :is="dynamicComponent"/>
    </KeepAlive>

5. Виртуализация списков

Что такое виртуализация:

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

Примеры:

Библиотеки, такие как vue-virtual-scroller, позволяют легко внедрить виртуализацию в Vue.js проект:

<template>
  <RecycleScroller
    class="scroller"
    :items="list"
    :item-size="32"
    key-field="id"
    v-slot="{ item }"
  >
    <div class="user">
      {{ item.name }}
    </div>
  </RecycleScroller>
</template>

<script>
export default {
  props: {
    list: Array,
  },
}
</script>

<style scoped>
.scroller {
  height: 100%;
}

.user {
  height: 32%;
  padding: 0 12px;
  display: flex;
  align-items: center;
}
</style>
  • Это особенно полезно при работе с длинными списками данных, такими как таблицы или галереи изображений.

6. Управление состоянием

Использование Pinia по мере необходимости:

  • Pinia — мощный инструмент для управления состоянием, но его чрезмерное использование может усложнить код и ухудшить производительность. Используйте Pinia для управления глобальным состоянием, а для локального состояния компонентов оставьте обычные методы Vue.

Мемоизация данных:

7. Оптимизация рендеринга изображений

Lazy Loading изображений:

  • Используйте ленивую загрузку изображений, чтобы загружать их только тогда, когда они появляются в области видимости пользователя:

    <img loading="lazy" alt="Lazy Loaded Image">

Использование современных форматов:

Форматы изображений, такие как WebP, обеспечивают лучшее сжатие без потери качества по сравнению с JPEG или PNG. Если возможно, используйте WebP и другие современные форматы:

<picture>
  <source srcset="image.webp" type="image/webp">
  <img src="image.jpg" alt="Optimized Image">
</picture>


Заключение

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

Комментарии (3)


  1. FedorCV
    29.08.2024 15:57

    Пожалуй одна из самых базовых частей разработки


  1. Arkham
    29.08.2024 15:57
    +1

    Для отображения webp использовать picture - это как использовать экскаватор вместо ложки. Проверьте в Accept заголовке поддержку webp, сохраните в состояние, и вставляйте в img ссылку сразу в нужном расширении.


    1. ovchinnikov-lxs Автор
      29.08.2024 15:57

      Согласен, работа с изображениями — это отдельная история, требующая более детального подхода. В своей практике я использую Nuxt вместе с модулем @nuxt/image и кастомным компонентом для изображений. Это позволяет получить полный контроль над всеми состояниями и отображением изображений — от работы с медиа-запросами до сжатия и оптимизации. Если интересно, могу попробовать написать статью на эту тему.