Vue ilovasining unumdorligini qanday optimallashtirish mumkin?

SeniorVue.js #vue #performance #optimization

Savol

Vue ilovasi unumdorligini optimallashtirishning qanday texnikalari mavjud: v-once/v-memo, <KeepAlive>, komponentlarni lazy loading qilish, ro'yxatlarni virtualizatsiya qilish?

Qisqa javob

Asosiy vositalar: v-once va v-memo shablonning statik yoki kamdan-kam o'zgaradigan qismlarini qayta render qilishdan o'tkazib yuboradi; <KeepAlive> faol bo'lmagan komponentlarning holati va DOM'ini qayta yaratish o'rniga saqlaydi; defineAsyncComponent bandlni bo'laklarga bo'ladi va og'ir komponentlarni talab bo'yicha yuklaydi; virtualizatsiya uzun ro'yxatning barcha emas, faqat ko'rinadigan elementlarini render qiladi.

Batafsil javob

v-once. Elementni/komponentni bir marta render qiladi va reaktiv ma'lumotlar ichida o'zgargan bo'lsa ham, boshqa hech qachon yangilamaydi. Aniq statik tarkib uchun mos keladi (masalan, mount qilinganda bir marta hisoblanadigan va keyin o'zgarmasligi kerak bo'lgan matn) — Vue bu tugunni keyingi yangilanishlardan chiqarib tashlaydi, diffing'da tejab qoladi.

v-memo. Bog'liqliklar massivini oladi: v-memo="[valueA, valueB]". Massivdagi qiymatlar oldingi render'dan beri o'zgarmagan bo'lsa, Vue quyi daraxtni qayta render qilishdan o'tkazib yuboradi — bu, mohiyatan, shablon bo'lagi uchun React.memo/memoizatsiyaning analogidir. Ota komponentning har qanday o'zgarishida har bir elementni qayta chizish qimmatga tushadigan, ammo aslida kamdan-kam o'zgaradigan katta ro'yxatlar uchun foydali.

<KeepAlive>. Dinamik komponentni (<component :is="..."> yoki <router-view> tarkibini) o'raydi va almashtirishda faol bo'lmagan komponentlar nusxalarini yo'q qilish o'rniga (odatda v-if/marshrut almashishi komponentni to'liq demount qiladi) keshlaydi. Bu komponent holatini (masalan, formaga kiritilgan matn, ro'yxat skrolli) saqlab qoladi va orqaga qaytishda qayta initsializatsiya/qayta so'rovlardan qutqaradi. Odatiy onMounted/onUnmounted o'rniga onActivated/onDeactivated hook'larini beradi. Nima va qancha keshlashni boshqarish uchun include/exclude/maxni qo'llab-quvvatlaydi.

Lazy loading (defineAsyncComponent). Birinchi render'da kerak bo'lmagan og'ir komponentlar (modallar, tahrirlovchilar, grafiklar) defineAsyncComponent(() => import('./Heavy.vue'))ga o'raladi. Kompilyator (Vite/webpack) bunday importni alohida chunk'ga bo'ladi, u faqat komponent haqiqatan kerak bo'lganda yuklanadi — bu boshlang'ich bandl hajmi va interaktivlikka qadar vaqtni (TTI) kamaytiradi. Vue Router'da marshrut komponentlarini lazy loading qilish ham xuddi shunday ishlaydi.

Uzun ro'yxatlarni virtualizatsiya qilish. Minglab <li>/jadval qatorlarini render qilishda Vue'ning samarali diffing'i ham yordam bermaydi — minglab tugunli DOM o'zi ham qimmatga tushadi (layout, paint, xotira). Virtualizatsiya DOM'ga faqat viewport'da ko'rinadigan elementlarni (plus kichik bufer) render qiladi, qolganini kerakli balandlikdagi bo'sh joy (spacer) bilan almashtiradi va skroll qilinganda elementlarni yuklaydi/tushiradi. Kutubxonalar orqali (vue-virtual-scroller, @tanstack/vue-virtual) yoki IntersectionObserver/scrollTop bo'yicha ko'rinadigan diapazonni qo'lda hisoblash orqali amalga oshiriladi.

Misol

<script setup>
import { ref, defineAsyncComponent } from 'vue'

// komponent faqat kerak bo'lganda alohida chunk sifatida yuklanadi
const HeavyChart = defineAsyncComponent(() =>
  import('./components/HeavyChart.vue')
)

const showChart = ref(false)
const staticLabel = 'Bu bir marta hisoblangan' // v-once uchun

const rows = ref(
  Array.from({ length: 1000 }, (_, i) => ({ id: i, value: i * 2 }))
)
</script>

<template>
  <!-- v-once: bir marta render qilinadi va boshqa yangilanmaydi -->
  <h3 v-once>{{ staticLabel }}</h3>

  <!-- v-memo: qatorni faqat uning value'si o'zgarganda qayta chizish -->
  <ul>
    <li v-for="row in rows" :key="row.id" v-memo="[row.value]">
      {{ row.id }}: {{ row.value }}
    </li>
  </ul>

  <!-- KeepAlive: komponent holati qayta ko'rsatilganda saqlanadi -->
  <button @click="showChart = !showChart">Grafikni almashtirish</button>
  <KeepAlive>
    <HeavyChart v-if="showChart" />
  </KeepAlive>
</template>

Qo'shimcha savollar

  • v-memo shablon qismini computed-props bilan alohida komponentga o'rashdan nimasi bilan farq qiladi?
  • Agar <KeepAlive> ishlatilmasa, tab'lar almashtirilganda forma holati bilan nima bo'ladi?
  • Vue Devtools orqali render'ning haqiqiy tor joylarini (component render timings) qanday aniqlash mumkin?