Мемоизация — это техника оптимизации, при которой результаты вычислений сохраняются и повторно используются при повторном вызове функции с теми же аргументами. Основная цель — сократить количество повторных вычислений и уменьшить нагрузку на систему.
В интерфейсных приложениях мемоизация применяется для:
В экосистеме Vue 3, на которой построена библиотека Element Plus, мемоизация реализуется через реактивные механизмы и специализированные API.
Библиотека Element Plus активно использует реактивную систему Vue для оптимизации работы компонентов. Компоненты интерфейса часто работают с:
Без мемоизации такие операции могут приводить к множественным повторным вычислениям при каждом обновлении состояния.
Мемоизация позволяет:
Основным механизмом мемоизации в Vue и Element Plus являются вычисляемые свойства (computed).
Вычисляемое свойство:
import { computed, ref } from 'vue'
const items = ref([
{ id: 1, price: 100 },
{ id: 2, price: 200 },
{ id: 3, price: 300 }
])
const totalPrice = computed(() => {
return items.value.reduce((sum, item) => sum + item.price, 0)
})
Особенности:
totalPrice вычисляется только при изменении
items;reduce.Это базовая форма мемоизации, встроенная в реактивную систему Vue.
Компонент таблицы часто работает с большим количеством данных.
Element Plus Vue.js
Без оптимизации операции:
могут выполняться при каждом обновлении компонента.
const search = ref('')
const rows = ref([...])
const filteredRows = computed(() => {
return rows.value.filter(row =>
row.name.toLowerCase().includes(search.value.toLowerCase())
)
})
Компонент таблицы:
<el-table :data="filteredRows">
<el-table-column prop="name" label="Name" />
</el-table>
Преимущества:
search или
rows;В интерфейсных приложениях могут выполняться дорогостоящие операции:
const statistics = computed(() => {
const result = {}
for (const item of items.value) {
if (!result[item.category]) {
result[item.category] = 0
}
result[item.category] += item.price
}
return result
})
Такой подход предотвращает:
watchEffectИногда вычисления должны выполняться не только при обращении к значению, но и при изменении зависимостей.
Для таких случаев применяется watchEffect.
import { watchEffect } from 'vue'
watchEffect(() => {
console.log(filteredRows.value)
})
Однако watchEffect не выполняет
мемоизацию. Он лишь отслеживает зависимости.
Поэтому для вычислений, которые должны кэшироваться, предпочтительнее
использовать computed.
Вычисляемые свойства обладают ленивой стратегией вычисления.
Это означает:
const heavyCalculation = computed(() => {
console.log('expensive calculation')
return items.value.map(x => x.price * 1.2)
})
Если heavyCalculation не используется в шаблоне или
коде:
Это особенно важно при сложных интерфейсах.
Кэш вычисляемого свойства зависит от реактивных источников.
Если внутри computed используются:
refreactivecomputedVue автоматически отслеживает зависимости.
const tax = ref(0.2)
const total = computed(() => {
return totalPrice.value * (1 + tax.value)
})
При изменении tax:
total сбрасывается;Иногда требуется мемоизация функций, а не только вычисляемых значений.
Для этого используется собственная реализация мемоизации.
function memoize(fn) {
const cache = new Map()
return function (...args) {
const key = JSON.stringify(args)
if (cache.has(key)) {
return cache.get(key)
}
const result = fn(...args)
cache.set(key, result)
return result
}
}
Использование:
const expensiveFunction = memoize((value) => {
return value * value
})
При повторных вызовах:
expensiveFunction(5)
expensiveFunction(5)
второй вызов возвращает результат из кэша.
В архитектуре Vue 3 часто используются composable-функции.
Мемоизация позволяет избежать повторной подготовки данных.
import { computed } from 'vue'
export function useSortedData(data) {
const sorted = computed(() => {
return [...data.value].sort((a, b) => a.price - b.price)
})
return {
sorted
}
}
При использовании в компоненте:
const { sorted } = useSortedData(products)
сортировка будет выполняться только при изменении
products.
При работе с большими таблицами и списками Element Plus часто применяется:
Это особенно актуально для компонентов:
Пример:
const visibleItems = computed(() => {
return items.value.slice(start.value, end.value)
})
Результат:
Чрезмерное использование computed может привести к:
Мемоизация должна применяться только для:
Если вычисляемое свойство возвращает объект, который затем изменяется, возможны ошибки.
Пример проблемы:
const settings = computed(() => {
return {
dark: theme.value === 'dark'
}
})
Если объект будет изменён:
settings.value.dark = false
кэш может стать неконсистентным.
Безопасный вариант:
Если внутри computed используется не реактивная
переменная, мемоизация может работать некорректно.
Пример:
let multiplier = 2
const value = computed(() => {
return price.value * multiplier
})
Изменение multiplier:
multiplier = 3
не вызовет пересчёт value.
Решение — использовать ref.
const multiplier = ref(2)
Правильное применение мемоизации позволяет значительно повысить производительность приложений, использующих Element Plus.
Основные преимущества:
Особенно заметен эффект при работе с:
Мемоизация становится важным инструментом оптимизации при разработке масштабных интерфейсов на базе Vue и Element Plus.