Оптимизация производительности во Vue
↑ 7.1 Vue под капотом · ← Предыдущая · → Следующая
Зачем это на собесе
Практический вопрос: «приложение тормозит, что вы будете делать». Нужен порядок действий, а не список приёмов.
Сначала измерить
Vue DevTools (Performance, Timeline), Chrome Performance, app.config.performance = true. Ищем: лишние рендеры, тяжёлые вычисления, большие списки.
Приёмы
| Проблема | Решение |
|---|---|
| Лишние ре-рендеры детей | стабильные props, defineProps по точным полям, computed вместо инлайн-выражений |
| Большой объект реактивен зря | shallowRef, markRaw, shallowReactive |
| Длинный список | виртуализация (vue-virtual-scroller, @tanstack/vue-virtual) |
| Статичное поддерево | v-once |
| Дорогой блок в списке | v-memo="[item.id, item.selected]" |
| Тяжёлые компоненты | defineAsyncComponent, lazy routes |
| Дорогие вычисления | computed (кэш), вынос в Web Worker |
| Переключение вкладок | <KeepAlive> |
| Всплеск watch | watchEffect осторожно, debounce |
Примеры
<div v-for="row in rows" :key="row.id" v-memo="[row.id, row.selected]">
<ExpensiveRow :row="row" />
</div>const HeavyChart = defineAsyncComponent(() => import('./HeavyChart.vue'))Ловушки
- computed с побочными эффектами или тяжёлым кодом, зависящим от многого;
v-ifиv-show:v-ifдороже при частом переключении, но экономит первый рендер;- передача новой функции или объекта в props при каждом рендере вызывает лишнее обновление ребёнка;
- глубокие
watchна больших структурах.
Вопросы с ответами
Что делать, если список из 10 тысяч строк тормозит?
Виртуализация: рендерим только видимые строки. Затем
shallowRefдля данных,v-memoи стабильные ключи.
Чем v-memo отличается от computed?
v-memoпропускает патчинг поддерева, если значения в массиве не изменились;computedкэширует значение выражения.