Мемоизация и кэширование

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


Мемоизация функций

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

import { ref, computed } from 'vue';

const numbers = ref([1, 2, 3, 4, 5]);

const sum = computed(() => {
  console.log('Вычисление суммы');
  return numbers.value.reduce((acc, n) => acc + n, 0);
});

В примере выше, computed автоматически кэширует результат функции до тех пор, пока numbers.value не изменится. Это и есть встроенная мемоизация. При каждом обращении к sum.value без изменения зависимостей повторное вычисление не происходит.


Разница между методами и вычисляемыми свойствами

Методы Vue.js вызываются при каждом рендере компонента, даже если входные данные не изменились:

methods: {
  sumNumbers() {
    console.log('Метод выполняется каждый раз');
    return this.numbers.reduce((acc, n) => acc + n, 0);
  }
}

В отличие от методов, computed свойства:

  • Автоматически кэшируются.
  • Пересчитываются только при изменении реактивных зависимостей.
  • Идеальны для затратных операций.

Использование computed вместо методов для вычислений с повторным доступом повышает производительность интерфейса.


Кэширование с помощью watch и реактивных ссылок

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

import { ref, watch } from 'vue';

const input = ref('');
const cachedResult = ref({});

watch(input, async (newVal) => {
  if (cachedResult.value[newVal]) return;
  const result = await fetchData(newVal);
  cachedResult.value[newVal] = result;
});

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


Мемоизация с помощью внешних библиотек

Для более сложных случаев можно использовать библиотеки типа lodash (_.memoize) или fast-memoize:

import memoize from 'fast-memoize';

const expensiveCalculation = memoize((num) => {
  console.log('Выполняется сложная операция');
  return num * 2; 
});

console.log(expensiveCalculation(5)); // Выполняется операция
console.log(expensiveCalculation(5)); // Используется кэш

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


Кэширование компонентов

Vue.js позволяет кэшировать компоненты с помощью <keep-alive>:

<template>
  <keep-alive>
    <MyComponent v-if="isVisible" />
  </keep-alive>
</template>

Особенности <keep-alive>:

  • Сохраняет состояние компонентов между переключениями.
  • Предотвращает повторный рендер при возврате к компоненту.
  • Работает с include и exclude для селективного кэширования.
<keep-alive include="UserProfile,Dashboard">
  <component :is="currentComponent" />
</keep-alive>

Практические рекомендации

  • Использовать computed для всех повторяющихся вычислений с зависимостями.
  • Применять watch с ref для кэширования результатов API-запросов.
  • Для функций, не зависящих от реактивных данных, использовать сторонние библиотеки мемоизации.
  • <keep-alive> помогает уменьшить количество монтирований компонентов и сохраняет их состояние.

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