Nowy standard. Twoje centrum tworzenia inteligentnego, szybkiego i zrównoważonego oprogramowania AI
Table of Contents
and 6 more
Dyrektywy Vue decydują o tym, kiedy Vue tworzy, aktualizuje, ukrywa lub pomija fragmenty DOM-u, więc wybór właściwej z nich to najtańszy sposób na poprawę wydajności w aplikacji Vue 3.
Najwięcej korzyści przynoszą zwykle trzy decyzje: v-if czy v-show przy treściach warunkowych, stabilne klucze na listach v-for oraz v-once albo v-memo dla poddrzew, które rzadko się zmieniają.
W tym przewodniku omawiamy każde z tych rozwiązań, wskazujemy, które zalecenia dotyczące dyrektyw zmieniły się wraz z przejściem z Vue 2 na Vue 3, i wyjaśniamy, kiedy optymalizacja dyrektyw nie jest miejscem, od którego warto zacząć.
Podsumowanie
Optymalizacja Vue.js za pomocą dyrektyw sprowadza się do tego, by powiedzieć Vue, ile pracy może pominąć.
Używaj v-show przy treściach często przełączanych, a v-if tam, gdzie coś pojawia się rzadko. Każdemu stanowymu elementowi v-for przypisz unikalny, stabilny klucz, a po v-once lub v-memo sięgaj tylko w zmierzonych wąskich gardłach, na przykład na długich listach. Starsze zalecenia, by używać v-pre i v-cloak dla szybkości, nie mają zastosowania w nowoczesnych aplikacjach Vue 3 z procesem budowania.
Najpierw profiluj: zmiany w dyrektywach rozwiązują konkretne problemy z ponownym renderowaniem, a nie problem wolnej aplikacji jako takiej.
Czym są dyrektywy Vue i dlaczego wpływają na wydajność?
Dyrektywy Vue to specjalne atrybuty v- w szablonie, które mówią Vue, jak renderować i aktualizować element: czy ma istnieć (v-if), czy ma być widoczny (v-show), ile kopii utworzyć (v-for) oraz czy w ogóle trzeba go jeszcze kiedyś aktualizować (v-once, v-memo). Każda z nich oznacza inną ilość pracy dla renderera Vue i przeglądarki.
Dlatego dwa szablony, które na ekranie wyglądają identycznie, pod obciążeniem mogą zachowywać się zupełnie inaczej. Dyrektywa użyta niewłaściwie rzadko od razu psuje aplikację. Częściej objawia się to dashboardem, który zaczyna się zacinać przy zmianie filtrów, formularzem gubiącym dane po zmianie kolejności listy albo długą tabelą, która zawiesza się przy każdej aktualizacji. To właśnie te problemy zauważają użytkownicy i zwykle da się je sprowadzić do kilku decyzji dotyczących dyrektyw w najbardziej obciążonych komponentach. Jeśli chcesz spojrzeć szerzej niż tylko na szablony, zajrzyj do naszego przewodnika po sprawdzonych technikach poprawy wydajności w Vue.js.
v-if vs v-show: które jest szybsze w Vue.js?
Żadne nie jest szybsze w każdej sytuacji. Dokumentacja Vue ujmuje to tak: v-if ma wyższy koszt przełączania, a v-show wyższy koszt początkowego renderowania. Wybieraj v-show, gdy coś przełącza się bardzo często, a v-if, gdy warunek raczej nie będzie się zmieniał w czasie działania aplikacji.
Różnica wynika z tego, co robi każda z tych dyrektyw. v-if dodaje element do DOM-u i go z niego usuwa, przy każdym przełączeniu niszcząc i odtwarzając jego komponenty potomne oraz nasłuchiwanie zdarzeń. Jest też leniwe: jeśli przy pierwszym renderowaniu warunek jest fałszywy, Vue nie renderuje niczego. v-show zawsze renderuje element i jedynie zmienia jego właściwość CSS display, więc przełączanie jest tanie, ale za renderowanie treści płacisz z góry, nawet jeśli użytkownik nigdy jej nie otworzy.
Dyrektywa | Co dzieje się przy przełączaniu | Koszt początkowego renderowania | Najlepsze zastosowanie |
|---|---|---|---|
v-if | Element i jego potomkowie są niszczeni i tworzeni od nowa | Niski, gdy warunek początkowo jest fałszywy (nic nie jest renderowane) | Treści pokazywane rzadko: modale, panele tylko dla administratora, stany błędu |
v-show | Zmienia się CSS | Zawsze ponosisz pełny koszt renderowania | Treści często przełączane: zakładki, listy rozwijane, akordeony |
Jeden praktyczny kompromis: v-if resetuje stan komponentu przy każdym przełączeniu, a v-show go zachowuje. Jeśli użytkownik wypełni połowę formularza w zwijanym panelu, v-show zachowa wpisane dane po zamknięciu i ponownym otwarciu. Czasem to właśnie sposób obsługi stanu, a nie szybkość, powinien decydować o wyborze.
Jak używać kluczy z v-for w Vue 3?
Każdemu elementowi przypisz unikalny, stabilny klucz identyfikujący sam element, zwykle będzie to ID z twoich danych: :key="item.id". Dokumentacja Vue mówi, że klucze powinny być prymitywami, czyli ciągami znaków albo liczbami, nigdy obiektami.
Bez kluczy Vue stosuje strategię „in-place patch”: gdy kolejność się zmienia, aktualizuje każdy element na jego bieżącej pozycji, zamiast przestawiać elementy. To wydajne rozwiązanie, ale bezpieczne tylko wtedy, gdy wynik listy nie zależy od stanu komponentów potomnych ani tymczasowego stanu DOM-u, na przykład wartości pól formularza. Gdy tak nie jest, brak klucza albo zły klucz objawia się już nie tylko spowolnieniem, ale po prostu błędem.
Najczęstszym błędem jest używanie indeksu tablicy jako klucza. Indeks jest unikalny, ale opisuje pozycję, a nie element, więc po wstawieniu, usunięciu albo zmianie kolejności elementów Vue dopasowuje niewłaściwe węzły DOM do niewłaściwych danych:
<!-- Avoid for dynamic lists: index describes position, not identity -->
<li v-for="(item, index) in items" :key="index">{{ item.name }}</li>
<!-- Do this: a stable ID follows the item wherever it moves -->
<li v-for="item in items" :key="item.id">{{ item.name }}</li>Dla statycznej listy zwykłego tekstu, której kolejność nigdy się nie zmienia, indeks, albo domyślne zachowanie Vue, w zupełności wystarczy. Tę dyscyplinę zachowaj dla list z komponentami, polami formularzy, przejściami albo zmianą kolejności.
Czy można używać v-if i v-for na tym samym elemencie?
Nie. W Vue 3 v-if ma wyższy priorytet niż v-for, więc warunek v-if nie ma dostępu do zmiennej pętli. Poniższy szablon w ogóle nie zadziała, bo podczas obliczania warunku item jest niezdefiniowane. (W Vue 2 kolejność była odwrotna, dlatego starsze poradniki wciąż pokazują ten wzorzec.)
<!-- Breaks in Vue 3: v-if runs before v-for, so item is undefined -->
<li v-for="item in items" v-if="item.visible" :key="item.id">
{{ item.name }}
</li>Zamiast tego przefiltruj listę we właściwości obliczanej. Jej wartość jest buforowana i przeliczana dopiero wtedy, gdy zmienia się items, więc szablon iteruje dokładnie po tym, co trzeba wyrenderować:
<script setup>
import { computed, ref } from 'vue'
const items = ref([])
const visibleItems = computed(() =>
items.value.filter((item) => item.visible)
)
</script>
<template>
<ul>
<li v-for="item in visibleItems" :key="item.id">
{{ item.name }}
</li>
</ul>
</template>Jeśli chcesz ukryć całą listę na podstawie warunku, umieść v-if na elemencie opakowującym albo na znaczniku <template>.
Kiedy v-once i v-memo poprawiają wydajność Vue?
v-once i v-memo to dwie wbudowane dyrektywy stworzone specjalnie z myślą o wydajności. Obie mówią Vue, by pomijał aktualizacje części szablonu, co ma największe znaczenie wtedy, gdy ten fragment jest duży, a jego komponent nadrzędny renderuje się często.
v-once renderuje element albo komponent tylko raz i od tego momentu traktuje go jako statyczny, zgodnie z dokumentacją API Vue. Sprawdza się przy treściach, które zależą od danych przy pierwszym renderowaniu, ale później nigdy nie muszą się zmieniać, na przykład w bloku regulaminu albo opisie produktu ładowanym tylko raz:
<section v-once>
<h2>{{ product.name }}</h2>
<div v-html="product.longDescription" />
</section>v-memo (Vue 3.2+) pomija aktualizacje poddrzewa, jeśli nie zmieniła się żadna wartość w tablicy zależności. Dokumentacja Vue opisuje je jako mikrooptymalizację do scenariuszy krytycznych wydajnościowo, najbardziej przydatną przy dużych listach v-for liczących ponad 1 000 elementów. W tym przykładzie zmiana zaznaczenia powoduje ponowne renderowanie tylko dwóch wierszy, których stan zaznaczenia się zmienił:
<div
v-for="item in list"
:key="item.id"
v-memo="[item.id === selectedId]"
>
<p>{{ item.name }} – selected: {{ item.id === selectedId }}</p>
<!-- ...more child nodes -->
</div>Ryzyko polega na nieaktualnym interfejsie. Jeśli w tablicy zależności zabraknie wartości używanej przez poddrzewo, Vue pominie aktualizacje, które powinny się wydarzyć, i nic cię o tym nie ostrzeże. Umieszczaj v-memo na tym samym elemencie co v-for, bo wewnątrz pętli nie działa, i dodawaj je dopiero wtedy, gdy profiler pokaże, że to lista jest wąskim gardłem. Przy listach liczących tysiące elementów wirtualizacja list, czyli renderowanie tylko wierszy znajdujących się blisko obszaru widocznego na ekranie, zwykle pomaga bardziej niż v-memo.
Czy v-pre i v-cloak przyspieszają aplikację Vue?
Nie w typowym projekcie Vue 3. Obie dyrektywy często pojawiają się na listach optymalizacji, ale ich udokumentowane zastosowania są węższe:
v-pre mówi Vue, by pominął kompilację elementu i jego potomków. Jak podaje dokumentacja Vue, jego główne zastosowanie to wyświetlanie surowej składni mustache, na przykład na stronach z dokumentacją pokazujących kod
{{ }}. Gdy szablony są wstępnie kompilowane na etapie budowania, nie przełoży się to na mierzalną różnicę w szybkości działania.v-cloak ukrywa surową składnię szablonu do momentu zamontowania komponentu. Dokumentacja Vue podaje, że jest potrzebny tylko w konfiguracjach bez etapu budowania, gdzie szablony zapisuje się bezpośrednio w stronie HTML. Jeśli twoja aplikacja używa komponentów single-file i bundlera takiego jak Vite, nie jest potrzebny.
Warto mieć oba narzędzia pod ręką na takie przypadki brzegowe, ale w standardowym SPA nie warto poświęcać im czasu podczas code review.
Kiedy warto napisać własną dyrektywę w Vue 3?
Własną dyrektywę pisz tylko wtedy, gdy potrzebujesz niskopoziomowego dostępu do DOM-u na zwykłych elementach, na przykład do automatycznego ustawiania fokusu w polu, obserwowania widoczności przy lazy loadingu albo integracji biblioteki działającej wyłącznie na DOM-ie. Dokumentacja Vue zaleca, by wszędzie tam, gdzie to możliwe, używać wbudowanych dyrektyw takich jak v-bind, bo są wydajniejsze i lepiej współpracują z renderowaniem po stronie serwera. Do wielokrotnego użycia logiki ze stanem lepiej sprawdzi się composable.
Jeśli już ją tworzysz, zadbaj o niski koszt wydajnościowy:
Używaj hooków Vue 3 (
created,beforeMount,mounted,beforeUpdate,updated,beforeUnmount,unmounted). Poradniki wspominające obindalboinsertedopisują Vue 2, a wsparcie dla Vue 2 zakończyło się 31 grudnia 2023 roku.Dbaj o to, by
updatedbyło lekkie. Uruchamia się przy każdej aktualizacji komponentu nadrzędnego, więc porównujbinding.valuezbinding.oldValuei pomijaj operacje na DOM-ie, gdy nic się nie zmieniło.Sprzątaj w
unmounted: usuwaj nasłuchiwacze zdarzeń, odłączaj obserwatory i czyść timery, bo inaczej będą powodować wycieki pamięci, gdy komponenty są montowane i odmontowywane.Unikaj używania własnych dyrektyw na komponentach. Stosują się tylko do węzła głównego, a w komponentach z wieloma węzłami głównymi Vue je ignoruje i zapisuje ostrzeżenie.
Skąd wiesz, czy to dyrektywy są problemem wydajnościowym?
Zanim cokolwiek zmienisz, zmierz problem. Vue DevTools ma profiler wydajności, a ustawienie app.config.performance = true dodaje znaczniki specyficzne dla Vue do panelu Performance w Chrome DevTools, jak opisano w przewodniku po wydajności Vue. Szukaj komponentów, które renderują się ponownie znacznie częściej, niż powinny, albo pojedynczej aktualizacji trwającej dziesiątki milisekund.
Jeśli problemem jest duża lista, masz do dyspozycji klucze, v-memo i wirtualizację. Jeśli aktualizuje się wiele komponentów potomnych, choć zmienił się tylko jeden, rozwiązaniem często jest stabilność propsów, czyli przekazywanie każdemu komponentowi podrzędnemu wartości, która zmienia się tylko wtedy, gdy dotyczy to właśnie jego, a nie dyrektywa. A jeśli aplikacja wolno się ładuje, zamiast wolno aktualizować, wybór dyrektyw nie pomoże. Wtedy znaczenie mają rozmiar bundla i pobieranie danych.
Najważniejsze wnioski
v-if ma wyższy koszt przełączania, a v-show wyższy koszt początkowego renderowania. Wybieraj je w zależności od tego, jak często treść się przełącza.
W elementach v-for używaj stabilnego ID jako klucza, a nie indeksu, wszędzie tam, gdzie elementy przechowują stan albo lista zmienia kolejność.
W Vue 3 nigdy nie umieszczaj v-if i v-for na tym samym elemencie. Filtruj dane we właściwości obliczanej.
v-once i v-memo pomijają aktualizacje, ale błędna tablica zależności v-memo prowadzi do cichego pojawiania się nieaktualnego interfejsu.
v-pre i v-cloak nie są narzędziami do poprawy wydajności w aplikacjach Vue 3 z procesem budowania.
Wybór dyrektyw to małe decyzje z widocznymi efektami
Optymalizacja dyrektyw polega na kilku świadomych decyzjach w komponentach, które wykonują najwięcej pracy, a nie na rozsypywaniu v-memo po całej bazie kodu: v-if albo v-show w zależności od częstotliwości przełączania treści, klucze zgodne z danymi i dyrektywy pomijające aktualizacje tylko tam, gdzie profiler pokazuje rzeczywiste wąskie gardło. Zespoły, które wcześnie ustalają takie konwencje, w code review i we wspólnych wzorcach komponentów, unikają większości błędów związanych z ponownym renderowaniem, których późniejsze namierzanie jest kosztowne. Jeśli twoja aplikacja Vue wyrosła już z początkowych założeń dotyczących wydajności, zespół tworzący Vue.js w Monterail może pomóc ci przeprowadzić audyt i ustalić, co warto poprawić w pierwszej kolejności.
FAQ o wydajności dyrektyw Vue





