useDeferredValue
useDeferredValue
— bu React hook’i bo’lib, ma’lum UI yangilanishlarini keyinroq vaqtlarga kechiktirish imkonini beradi. Bu, ayniqsa, dastur katta yuklama yoki hisoblash bilan bog’liq murakkab vazifalar bilan ishlayotgan holatlarda foydali bo’lib, yangilanishlarni ustuvorlik asosida boshqarishga va silliq o’tishlarni ta’minlashga, foydalanuvchi bilan ishlash qulayligini yaxshilashga yordam beradi.
Dastlabki render paytida qaytarilgan kechiktirilgan qiymat taqdim etilgan qiymat bilan bir xil bo’ladi. Keyingi yangilanishlarda esa, useDeferredValue
eski qiymatni uzoqroq saqlash orqali silliq foydalanuvchi bilan ishlash qulayligini ta’minlaydi va yangi qiymatga o’tishni kechiktiradi, ayniqsa ko’p hisoblashni talab qiluvchi vaziyatlarda. Bu ko’p marta eski va yangi qiymatlar bilan qayta render qilishni emas, balki boshqarilgan yangilanishni anglatadi. Ushbu mexanizm yangilanguncha eskisini ko’rsatish(stale-while-revalidate)
strategiyasiga o’xshaydi, yangi qiymatlarni kutish davomida U’Ining javob beruvchanligini saqlaydi.
useDeferredValue’ning ilk implementatsiyasi
React’ning commit tarixini ko’rib chiqsak, useDeferredValue
ning birinchi implementatsiyasi quyidagicha bo’lgan:
function useDeferredValue(value) {
const [newValue, setNewValue] = useState(value); // faqat dastlabki qiymatni saqlaydi
useEffect(() => {
// o'zgarganda qaytarilgan qiymatni transition’da yangilaydi,
// "kechiktirib" turadi
startTransition(() => {
setNewValue(value);
});
}, [value]);
return newValue;
}
Keling, ushbu kod nima qilayotganini tushuntiramiz. Dastlab, berilgan dastlabki qiymat bilan newValue
state’i o’rnatiladi. Keyin bu funksiya useEffect
hook’ini qo’llab, ushbu qiymatdagi o’zgarishlarni kuzatadi. O’zgarish aniqlanganda, yangilanishni kechiktirish uchun muhim bo’lgan startTransition
funksiyasi chaqiriladi.
startTransition
ichidagi state setNewValue
yordamida yangi qiymatga yangilanadi. startTransition
dan foydalanish React’ga bu yangilanishni shoshilinch emasligini bildiradi, bu esa React’ga boshqa muhimroq yangilanishlarga ustuvorlik berish imkonini beradi. Bu, deyarli hozirgi kunda useDeferredValue
qanday ishlashiga o’xshaydi va bu haqidagi tushunchamiz uchun foydali bo’lishi kerak.
useDeferredValue
— bu React’ning concurrent’lik xususiyatlarining bir qismi bo’lib, ayrim state yangilanishlarini kechiktirish orqali to’xtatish imkoniyatini taqdim etadi.
Komponent kechiktirilgan qiymat bilan qayta render qilinganda, React bir muddat eski qiymatni saqlab turadi, bu esa yuqori ustuvorlikdagi yangilanishlar past ustuvorlikdagilardan oldinroq ishlov berilishiga imkon beradi. Bu, renderlash ishini kichik qismlarga bo’lib, vaqt davomida tarqatib beradi, javob beruvchanligini yaxshilaydi va yuqori ustuvorlikdagi yangilanishlar (masalan, foydalanuvchi interaktivligi) past ustuvorlikdagilar tomonidan kechiktirilmasligini ta’minlaydi, shu bilan foydalanuvchi bilan ishlash qulayligini oshiradi.
useDeferredValue hook’ining maqsadi
useDeferredValue
ning asosiy maqsadi, kamroq ahamiyatga ega yangilanishlarni render qilishlikni kechiktirishga imkon berishdir. Bu, foydalanuvchi interaktivligi kabi muhimroq yangilanishlarni serverdan yangilangan ma’lumotlarni ko’rsatish kabi kamroq muhim bo’lgan yangilanishlarga nisbatan ustuvorlik berish uchun juda foydalidir.
useDeferredValue
dan foydalanish orqali, siz foydalanuvchi bilan ishlash qulayligini yanada qulay va silliqroq ta’minlashingiz va ilovangizning katta yuklama ostida yoki murakkab operatsiyalar bilan shug’ullanayotganda ham javob beruvchanligini saqlab qolishingiz mumkin.
Foydalanish misoli
useDeferredValue
’dan foydalanish uchun, uni React paketidan import qilishingiz va kechiktirilishi kerak bo’lgan qiymatni argument sifatida berishingiz kerak. Hook keyin sizning komponentingizda ishlatilishi mumkin bo’lgan kechiktirilgan versiyasini qaytaradi.
Quyida useDeferredValue
ni oddiy ilovada qanday ishlatishni ko’rsatadigan sodda misol keltirilgan:
import React, { memo, useState, useDeferredValue } from "react";
function App() {
const [searchValue, setSearchValue] = useState("");
const deferredSearchValue = useDeferredValue(searchValue);
return (
<div>
<input
type="text"
value={searchValue}
onChange={(event) => setSearchValue(event.target.value)}
/>
<SearchResults searchValue={deferredSearchValue} />
</div>
);
}
const SearchResults = memo(({ searchValue }) => {
// Qidiruvni amalga oshirish va natijalarni render qilish
});
Ushbu misolda, bizda qidiruv input’i va qidiruv natijalarini ko’rsatuvchi SearchResults
komponenti mavjud. Biz useDeferredValue
dan qidiruv natijalarini renderlashni kechiktirish uchun foydalanamiz, bu esa ilovaga foydalanuvchi kiritmalarini ustuvorlashtirish va natijalar ro’yxatini renderlash qiyin bo’lganda ham javob beruvchan bo’lib qolishiga yordam beradi.
Buni yanada batafsil tushunib olaylik:
- Oldingi boblarda muhokama qilinganidek, biz komponentda
memo
dan foydalanamiz, shunda u keraksiz yangilanmaydi. - Yangilanish sodir bo’lganda, bu natijalarning renderlanishi qiyin bo’lgani uchun ishlash samaradorligi muammolarini keltirib chiqaradi.
- Biz unga kechiktirilgan prop, ya’ni
deferredSearchValue
berganimizda, bu prop o’zi zarur render ishlari tugagandan keyin yangilanganligi sababli, komponent ham yangilanadi. Shunday qilib, komponent faqat muhim ishlar bajarilganda, masalan, matn input maydonini yangilaganda qayta renderlanadi.
Debounce va throttling texnikasi
Yana kimdir, “Nega shunchaki searchValue
ni debounce qilish yoki throttling qilib qo’ya qolmaymiz?” deb so’rashi mumkin.
Ajoyib savol. Keling, ularni solishtiraylik:
- Debouncing: Ro’yxatni yangilashdan oldin pauza qilishni o’z ichiga oladi, foydalanuvchi yozishni tugatguncha kutadi, masalan, bir soniyalik kechikish.
- Throttling: Ro’yxatni belgilangan vaqt oralig’ida yangilaydi, masalan, bir soniyadan ko’p emas.
Ushbu usullar ba’zi vaziyatlarda samarali bo’lishi mumkin, lekin useDeferredValue
render optimizatsiyasi uchun yanada moslashtirilgan yechim sifatida paydo bo’ladi, chunki u foydalanuvchining qurilmasining ishlash imkoniyatlariga muvofiq ravishda moslashadi va hech qanday tasodifiy kechikishni talab qilmaydi.
Asosiy farqlar
useDeferredValue
ning asosiy farqi, kechikishlarga dinamik yondashuvdir. Bu ma’lum bir kechikish vaqtini belgilash zaruratini yo’q qiladi. Yuqori samarali qurilmada, masalan, kuchli noutbukda, qayta render qilishdagi kechikish deyarli sezilmaydi, deyarli darhol sodir bo’ladi. Aksincha, sekinroq qurilmalarda renderlash kechikishi tegishlicha moslashadi, foydalanuvchi kiritishiga javoban ro’yxatni yangilashda biroz orqada qolishi, qurilmaning tezligiga proporsional bo’ladi.
Qo’shimcha afzalliklar
Bundan tashqari, useDeferredValue
ning kechiktirilgan qayta renderlarni to’xtatish imkoniyatida katta afzalligi bor. Agar React katta ro’yxatni qayta ishlayotgan bo’lsa va foydalanuvchi yangi tugma bosishi bilan kiritilsa, React qayta renderlashni to’xtatishi, yangi kiritishga javob berishi va keyin orqa fon jarayonida renderlash jarayonini davom ettirishi mumkin. Bu, debouncing va throttling bilan taqqoslaganda, yangilanishlarni kechiktirishiga qaramasdan, renderlash davomida interaktivlikni bloklaydi va disjoint (bir-biriga mos kelmaslik) muammosiga olib kelishi mumkin.
Biroq, debouncing va throttling renderlash bilan bevosita bog’liq bo’lmagan vaziyatlarda hali ham foydali. Masalan, ular tarmoq so’rovlarining tezligini kamaytirishda samarali bo’lishi mumkin. Ushbu texnikalarni useDeferredValue
bilan birga kengaytirilgan optimizatsiya strategiyasi uchun ham ishlatish mumkin.
useDeferredValue
dan foydalanishning afzalliklari
Bular asosida, React ilovalarida useDeferredValue
dan foydalanishning bir necha afzalliklarini ko’rib o’tamiz:
- Yaxshilangan javob beruvchanlik: Misolda, foydalanuvchi qidiruv maydoniga yozganda, kiritish maydoni darhol yangilanadi va natijalar kechiktiriladi. Agar foydalanuvchi tezda 5 ta belgini ketma-ket yozsa, kiritish maydoni darhol besh marta yangilanadi va
searchValue
faqat foydalanuvchi yozishni to’xtatganda bir marta render qilinadi. 1-4 belgilar uchunSearchResults
ning renderlanishi yangi qiymatlar bilan to’xtatiladi. - Deklarativ ustuvorlik:
useDeferredValue
ilovangizda yangilanishlar ustuvorligini boshqarish uchun oddiy va deklarativ usulni taqdim etadi. Yangilanishlarni kechiktirish uchun logikani hook ichida joylashtirish orqali, komponent kodingizni toza va ilovangizning muhim jihatlariga diqqatni jamlashga imkon beradi. - Resurslardan yaxshiroq foydalanish: Kechiktirilgan kamroq muhim bo’lgan yangilanishlar bilan
useDeferredValue
ilovangizning mavjud resurslaridan yaxshiroq foydalanishiga yordam beradi. Bu ishlashdagi qiyinchiliklar ehtimolini kamaytirishga va ilovangizning umumiy ishlashini yaxshilashga yordam beradi.
useDeferredValue qachon ishlatiladi
useDeferredValue
asosan ilovangizda ba’zi yangilanishlarni boshqalardan ustun qo’yish zarur bo’lgan vaziyatlarda juda foydali. useDeferredValue
dan foydalanishni ko’rib chiqish mumkin bo’lgan ba’zi umumiy vaziyatlar:
- Katta ma’lumotlar to’plamlarini qidirish yoki filtr qilish
- Murakkab vizualizatsiyalar yoki animatsiyalarni renderlash
- Serverdan kelgan ma’lumotlarni orqa fon rejimida yangilash
- Foydalanuvchi interaktivligiga ta’sir ko’rsatishi mumkin bo’lgan hisoblash jihatdan qiyin operatsiyalarni boshqarish
Keling, useDeferredValue
ni ayniqsa foydali bo’lishi mumkin bo’lgan bir misolga qaraylik. Tasavvur qilingki, biz foydalanuvchi input’i asosida filtrlanishi kerak bo’lgan katta ro’yxatdagi elementlar mavjud. Katta ro’yxatni filtr qilish hisoblash jihatdan qiyin bo’lishi mumkin, shuning uchun useDeferredValue
dan foydalanish ilovani javobgar holda saqlashga yordam beradi:
import React, { memo, useState, useMemo, useDeferredValue } from "react";
function App() {
const [filter, setFilter] = useState("");
const deferredFilter = useDeferredValue(filter);
const items = useMemo(() => generateLargeListOfItems(), []);
const filteredItems = useMemo(() => {
return items.filter((item) => item.includes(deferredFilter));
}, [items, deferredFilter]);
return (
<div>
<input
type="text"
value={filter}
onChange={(event) => setFilter(event.target.value)}
/>
</div>
<ItemList items={filteredItems} />
);
}
const ItemList = memo(({ items }) => {
// Elementlar ro'yxatini renderlash
});
function generateLargeListOfItems() {
// Misol uchun katta elementlar ro'yxatini yaratish
}
Ushbu misolda, filtrlangan ro’yxatni renderlashni kechiktirish uchun useDeferredValue
dan foydalanamiz. Foydalanuvchi filtr input maydonida yozganda, kechiktirilgan qiymat kamroq tez-tez yangilanadi, bu ilovaga foydalanuvchi input’ini ustuvorlash va tezkor javob beruvchanligini saqlashga imkon beradi.
useMemo
hook’i items
va filteredItems
massivlarini memoizatsiya qilish uchun ishlatiladi, bu esa keraksiz qayta renderlash va qayta hisoblashlarni oldini oladi. Bu esa ilovaning ishlashini yanada yaxshilaydi.
useDeferredValue’dan qachon foydalanmaslik kerak
useDeferredValue
ba’zi vaziyatlarda foydali bo’lishi mumkin bo’lsa-da, uning ayrim ijobiy va salbiy jihatlarini ko’rib chiqish muhimdir. Ya’ni, yangilanishlarni kechiktirish orqali, foydalanuvchiga ko’rsatiladigan ma’lumotlar biroz eski bo’lishi mumkin. Bu kamroq muhim yangilanishlar uchun odatda qabul qilinadi, ammo foydalanuvchilarga eski ma’lumotlarni ko’rsatishning oqibatlarini hisobga olish zarur.
useDeferredValue
dan foydalanish yoki foydalanmaslik haqida qaror qabul qilishda o’zingizga berishingiz mumkin bo’lgan yaxshi savol: “Ushbu yangilanish foydalanuvchi input’imi?”
React’ning React deb atalishining sababi shundaki, u bizning veb-ilovalarimizni voqealarga reaksiya qilishga imkon beradi. Foydalanuvchi biror narsa kiritganda, natijani kutishi kerak bo’lsa, bu yangilanishni kechiktirishga arziydimi yoki yo’qmi deb o’ylash kerak. Boshqa barcha yangilanishlar esa kechiktirilishi mumkin.
useDeferredValue
dan foydalanish ilovangizning katta yuklama ostida ham javob beruvchanligini yaxshilashi mumkin, ammo bu uni muammolarni hal qilishning asosiy yechimi sifatida ko’rmaslik kerak. Har doim esda tutingki, samarali kod yozish va keraksiz hisoblashlardan qochish - samaradorlikni oshirishning eng yaxshi usuli.