जनरेटिव डेटा इंटेलिजेंस

SvelteKit में कैशिंग डेटा

दिनांक:

My पिछले पोस्ट SvelteKit का एक व्यापक अवलोकन था जहाँ हमने देखा कि वेब विकास के लिए यह कितना अच्छा उपकरण है। यह पोस्ट हमने वहां क्या किया है और प्रत्येक डेवलपर के पसंदीदा विषय में डुबकी लगाएगा: कैशिंग. इसलिए, मेरी पिछली पोस्ट को पढ़ना सुनिश्चित करें यदि आपने पहले से नहीं किया है। इस पोस्ट के लिए कोड GitHub पर उपलब्ध है, के रूप में के रूप में अच्छी तरह से एक लाइव डेमो.

यह पोस्ट डेटा हैंडलिंग के बारे में है। हम कुछ प्रारंभिक खोज कार्यक्षमता जोड़ेंगे जो पृष्ठ की क्वेरी स्ट्रिंग (अंतर्निहित SvelteKit सुविधाओं का उपयोग करके) को संशोधित करेगी, और पृष्ठ के लोडर को फिर से ट्रिगर करेगी। लेकिन, हमारे (काल्पनिक) डेटाबेस को केवल फिर से क्वेरी करने के बजाय, हम कुछ कैशिंग जोड़ेंगे ताकि पूर्व की खोजों को फिर से खोजा जा सके (या बैक बटन का उपयोग करके) पहले से पुनर्प्राप्त डेटा को कैश से जल्दी से दिखाया जा सके। हम देखेंगे कि कैश्ड डेटा के वैध रहने की अवधि को कैसे नियंत्रित किया जाए और इससे भी महत्वपूर्ण बात यह है कि सभी कैश्ड मानों को मैन्युअल रूप से कैसे अमान्य किया जाए। सोने पर सुहागा के रूप में, हम यह देखेंगे कि कैशे को शुद्ध करते हुए, म्यूटेशन के बाद, हम वर्तमान स्क्रीन, क्लाइंट-साइड पर डेटा को मैन्युअल रूप से कैसे अपडेट कर सकते हैं।

यह एक लंबी, अधिक कठिन पोस्ट होगी जो मैं आमतौर पर लिखता हूं क्योंकि हम कठिन विषयों को कवर कर रहे हैं। यह पोस्ट अनिवार्य रूप से आपको दिखाएगी कि लोकप्रिय डेटा उपयोगिताओं की सामान्य विशेषताओं को कैसे लागू किया जाए प्रतिक्रिया-प्रश्न; लेकिन बाहरी लाइब्रेरी को खींचने के बजाय, हम केवल वेब प्लेटफॉर्म और SvelteKit सुविधाओं का उपयोग करेंगे।

दुर्भाग्य से, वेब प्लेटफ़ॉर्म की विशेषताएं थोड़ी निम्न स्तर की हैं, इसलिए हम आपकी अपेक्षा से थोड़ा अधिक काम कर रहे होंगे। उल्टा यह है कि हमें किसी बाहरी पुस्तकालय की आवश्यकता नहीं होगी, जो बंडल के आकार को अच्छा और छोटा रखने में मदद करेगा। कृपया उन दृष्टिकोणों का उपयोग न करें जो मैं आपको दिखाने जा रहा हूँ जब तक कि आपके पास इसका कोई अच्छा कारण न हो। कैशिंग गलत होना आसान है, और जैसा कि आप देखेंगे, इसमें थोड़ी जटिलता है जिसके परिणामस्वरूप आपका एप्लिकेशन कोड होगा। उम्मीद है कि आपका डेटा स्टोर तेज़ है, और आपका UI ठीक है जिससे SvelteKit हमेशा किसी दिए गए पेज के लिए आवश्यक डेटा का अनुरोध कर सकता है। अगर ऐसा है तो उसे अकेला छोड़ दें। सादगी का आनंद लें। लेकिन यह पोस्ट आपको कुछ तरकीबें बताएगी जब ऐसा होना बंद हो जाता है।

प्रतिक्रिया-प्रश्न की बात करते हुए, it अभी जारी किया गया था Svelte के लिए! इसलिए यदि आप स्वयं को मैन्युअल कैशिंग तकनीकों पर निर्भर पाते हैं बहुत, उस प्रोजेक्ट की जांच करना सुनिश्चित करें, और देखें कि क्या यह मदद कर सकता है।

की स्थापना

शुरू करने से पहले, आइए इसमें कुछ छोटे बदलाव करें कोड हमारे पास पहले था. यह हमें SvelteKit की कुछ अन्य विशेषताओं को देखने का बहाना देगा और इससे भी महत्वपूर्ण बात यह है कि हमें सफलता के लिए तैयार करेगा।

सबसे पहले, चलिए अपने डेटा लोडिंग को अपने लोडर से अंदर ले जाते हैं +page.server.js एक को एपीआई मार्ग. हम एक बना देंगे +server.js में फाइल routes/api/todos, और फिर a . जोड़ें GET समारोह। इसका मतलब है कि अब हम (डिफ़ॉल्ट GET क्रिया का उपयोग करके) को लाने में सक्षम होंगे /api/todos पथ। हम पहले की तरह ही डेटा लोडिंग कोड जोड़ेंगे।

import { json } from "@sveltejs/kit";
import { getTodos } from "$lib/data/todoData"; export async function GET({ url, setHeaders, request }) { const search = url.searchParams.get("search") || ""; const todos = await getTodos(search); return json(todos);
}

इसके बाद, हमारे पास जो पेज लोडर था, उसे लेते हैं, और बस फ़ाइल का नाम बदलें +page.server.js सेवा मेरे +page.js (या .ts यदि आपने टाइपस्क्रिप्ट का उपयोग करने के लिए अपनी परियोजना को मचान बनाया है)। यह हमारे लोडर को सर्वर लोडर के बजाय "सार्वभौमिक" लोडर में बदल देता है। SvelteKit डॉक्स अंतर की व्याख्या करें, लेकिन एक सार्वभौमिक लोडर सर्वर और क्लाइंट दोनों पर चलता है। हमारे लिए एक फायदा यह है कि fetch हमारे नए एंडपॉइंट में कॉल सीधे हमारे ब्राउज़र से (प्रारंभिक लोड के बाद) चलेगा, ब्राउज़र के नेटिव का उपयोग करके fetch समारोह। हम थोड़े समय में मानक HTTP कैशिंग जोड़ देंगे, लेकिन अभी के लिए, हम केवल एंडपॉइंट को कॉल करेंगे।

export async function load({ fetch, url, setHeaders }) { const search = url.searchParams.get("search") || ""; const resp = await fetch(`/api/todos?search=${encodeURIComponent(search)}`); const todos = await resp.json(); return { todos, };
}

अब हम अपने में एक सरल रूप जोड़ते हैं /list पेज:

<div class="search-form"> <form action="/hi/list"> <label>Search</label> <input autofocus name="search" /> </form>
</div>

हां, फॉर्म सीधे हमारे सामान्य पेज लोडर को लक्षित कर सकते हैं। अब हम खोज बॉक्स में खोज शब्द जोड़ सकते हैं, हिट करें दर्ज, और URL के क्वेरी स्ट्रिंग में एक "खोज" शब्द जोड़ा जाएगा, जो हमारे लोडर को फिर से चलाएगा और हमारे टू-डू आइटम खोजेगा।

खोज फार्म

हमारी देरी को भी बढ़ाते हैं todoData.js में फाइल /lib/data. जब हम इस पोस्ट के माध्यम से काम करते हैं तो इससे यह देखना आसान हो जाता है कि डेटा कब है और कैश नहीं है।

export const wait = async amount => new Promise(res => setTimeout(res, amount ?? 500));

याद रखें, इस पोस्ट का पूरा कोड है सभी GitHub पर, अगर आपको इसका संदर्भ देना है।

बेसिक कैशिंग

आइए अपने में कुछ कैशिंग जोड़कर आरंभ करें /api/todos समापन बिंदु। हम वापस अपने पास जाएंगे +server.js फाइल करें और हमारा पहला कैश-कंट्रोल हेडर जोड़ें।

setHeaders({ "cache-control": "max-age=60",
});

…जो पूरे समारोह को इस तरह दिखने देगा:

export async function GET({ url, setHeaders, request }) { const search = url.searchParams.get("search") || ""; setHeaders({ "cache-control": "max-age=60", }); const todos = await getTodos(search); return json(todos);
}

हम शीघ्र ही मैन्युअल अमान्यकरण पर विचार करेंगे, लेकिन यह सभी फ़ंक्शन इन API कॉल को 60 सेकंड के लिए कैश करने के लिए कहते हैं। इसे आप जो चाहें सेट करें, और आपके उपयोग के मामले के आधार पर, stale-while-revalidate देखने लायक भी हो सकता है।

और ऐसे ही, हमारे प्रश्न संचित हो रहे हैं।

DevTools में कैश।

नोट सुनिश्चित करें कि आप अन-चेक करें चेकबॉक्स जो विकास उपकरणों में कैशिंग को अक्षम करता है।

याद रखें, यदि ऐप पर आपका प्रारंभिक नेविगेशन सूची पृष्ठ है, तो उन खोज परिणामों को SvelteKit में आंतरिक रूप से कैश किया जाएगा, इसलिए उस खोज पर लौटने पर DevTools में कुछ भी देखने की अपेक्षा न करें।

कैश्ड क्या है, और कहाँ है

हमारे ऐप का हमारा सबसे पहला, सर्वर द्वारा प्रदान किया गया लोड (यह मानते हुए कि हम /list पेज) सर्वर पर लाया जाएगा। SvelteKit इस डेटा को क्रमबद्ध करेगा और हमारे क्लाइंट को नीचे भेजेगा। क्या अधिक है, यह निरीक्षण करेगा Cache-Control हैडर प्रतिक्रिया पर, और कैश विंडो के भीतर उस समापन बिंदु कॉल के लिए इस कैश्ड डेटा का उपयोग करना जानेंगे (जिसे हम पुट उदाहरण में 60 सेकंड के लिए सेट करते हैं)।

उस प्रारंभिक लोड के बाद, जब आप पृष्ठ पर खोज करना प्रारंभ करते हैं, तो आपको अपने ब्राउज़र से नेटवर्क अनुरोधों को देखना चाहिए /api/todos सूची। जैसे ही आप उन चीज़ों को खोजते हैं जिन्हें आप पहले ही खोज चुके हैं (पिछले 60 सेकंड के भीतर), प्रतिक्रियाएँ कैश होने के तुरंत बाद लोड होनी चाहिए।

इस दृष्टिकोण के साथ विशेष रूप से अच्छी बात यह है कि, चूंकि यह ब्राउज़र की मूल कैशिंग के माध्यम से कैशिंग है, ये कॉल (आप कैश बस्टिंग को कैसे प्रबंधित करते हैं, इस पर निर्भर करते हुए) कैश करना जारी रख सकते हैं, भले ही आप पेज को फिर से लोड करते हैं (इसके विपरीत) आरंभिक सर्वर-साइड लोड, जो हमेशा समापन बिंदु को ताज़ा कहता है, भले ही उसने इसे पिछले 60 सेकंड के भीतर किया हो)।

जाहिर है कि डेटा कभी भी बदल सकता है, इसलिए हमें इस कैश को मैन्युअल रूप से शुद्ध करने का एक तरीका चाहिए, जिसे हम आगे देखेंगे।

कैश अमान्य

अभी, डेटा 60 सेकंड के लिए कैश किया जाएगा। चाहे कुछ भी हो, एक मिनट के बाद, हमारे डेटास्टोर से ताज़ा डेटा खींच लिया जाएगा। हो सकता है कि आप एक छोटी या अधिक समयावधि चाहते हों, लेकिन यदि आप कुछ डेटा म्यूट करते हैं और अपना कैश तुरंत साफ़ करना चाहते हैं तो क्या होता है ताकि आपकी अगली क्वेरी अद्यतित रहे? हम अपने नए को भेजे जाने वाले URL में एक क्वेरी-बस्टिंग मान जोड़कर इसे हल करेंगे /todos समापन बिंदु।

आइए इस कैश बस्टिंग वैल्यू को कुकी में स्टोर करें। वह मान सर्वर पर सेट किया जा सकता है लेकिन क्लाइंट पर अभी भी पढ़ा जा सकता है। आइए कुछ नमूना कोड देखें।

हम एक बना सकते हैं +layout.server.js फ़ाइल हमारे बहुत मूल में है routes फ़ोल्डर। यह एप्लिकेशन स्टार्टअप पर चलेगा, और प्रारंभिक कुकी मान सेट करने के लिए एक आदर्श स्थान है।

export function load({ cookies, isDataRequest }) { const initialRequest = !isDataRequest; const cacheValue = initialRequest ? +new Date() : cookies.get("todos-cache"); if (initialRequest) { cookies.set("todos-cache", cacheValue, { path: "/", httpOnly: false }); } return { todosCacheBust: cacheValue, };
}

आपने गौर किया होगा isDataRequest कीमत। याद रखें, लेआउट कभी भी क्लाइंट कोड कॉल को फिर से चलाएंगे invalidate(), या कभी भी हम एक सर्वर क्रिया चलाते हैं (यह मानते हुए कि हम डिफ़ॉल्ट व्यवहार को बंद नहीं करते हैं)। isDataRequest उन पुन: चलने को इंगित करता है, और इसलिए हम कुकी को केवल तभी सेट करते हैं यदि वह है false; अन्यथा, हम वही भेजते हैं जो पहले से ही वहाँ है।

RSI httpOnly: false ध्वज का भी महत्व है। यह हमारे क्लाइंट कोड को इन कुकी मानों को पढ़ने की अनुमति देता है document.cookie. यह आमतौर पर एक सुरक्षा चिंता होगी, लेकिन हमारे मामले में ये अर्थहीन संख्याएं हैं जो हमें कैश या बस्ट को कैश करने की अनुमति देती हैं।

कैश मान पढ़ना

हमारा यूनिवर्सल लोडर वह है जिसे हम कहते हैं /todos समापन बिंदु। यह सर्वर या क्लाइंट पर चलता है, और हमें उस कैश वैल्यू को पढ़ने की जरूरत है जिसे हम अभी सेट करते हैं, चाहे हम कहीं भी हों। यदि हम सर्वर पर हैं तो यह अपेक्षाकृत आसान है: हम कॉल कर सकते हैं await parent() पैरेंट लेआउट से डेटा प्राप्त करने के लिए। लेकिन क्लाइंट पर, हमें पार्स करने के लिए कुछ ग्रॉस कोड का उपयोग करने की आवश्यकता होगी document.cookie:

export function getCookieLookup() { if (typeof document !== "object") { return {}; } return document.cookie.split("; ").reduce((lookup, v) => { const parts = v.split("="); lookup[parts[0]] = parts[1]; return lookup; }, {});
} const getCurrentCookieValue = name => { const cookies = getCookieLookup(); return cookies[name] ?? "";
};

सौभाग्य से, हमें केवल एक बार इसकी आवश्यकता होती है।

कैश मान भेजा जा रहा है

लेकिन अब हमें चाहिए भेजें यह मूल्य हमारे लिए /todos समापन बिंदु।

import { getCurrentCookieValue } from "$lib/util/cookieUtils"; export async function load({ fetch, parent, url, setHeaders }) { const parentData = await parent(); const cacheBust = getCurrentCookieValue("todos-cache") || parentData.todosCacheBust; const search = url.searchParams.get("search") || ""; const resp = await fetch(`/api/todos?search=${encodeURIComponent(search)}&cache=${cacheBust}`); const todos = await resp.json(); return { todos, };
}

getCurrentCookieValue('todos-cache') यह देखने के लिए इसमें एक चेक है कि क्या हम क्लाइंट पर हैं (दस्तावेज़ के प्रकार की जाँच करके), और यदि हम हैं तो कुछ भी नहीं लौटाते हैं, जिस बिंदु पर हम जानते हैं कि हम सर्वर पर हैं। फिर यह हमारे लेआउट से मान का उपयोग करता है।

कैश को नष्ट करना

परंतु कैसे क्या हम वास्तव में उस कैश बस्टिंग वैल्यू को अपडेट करते हैं जब हमें इसकी आवश्यकता होती है? चूंकि यह एक कुकी में संग्रहीत है, हम इसे किसी भी सर्वर क्रिया से इस तरह कॉल कर सकते हैं:

cookies.set("todos-cache", cacheValue, { path: "/", httpOnly: false });

कार्यान्वयन

यह सब यहाँ से ढलान पर है; हमने कड़ी मेहनत की है। हमने उन विभिन्न वेब प्लेटफ़ॉर्म आदिमों को शामिल किया है जिनकी हमें आवश्यकता है, साथ ही यह भी कि वे कहाँ जाते हैं। आइए अब कुछ आनंद लें और इसे एक साथ जोड़ने के लिए एप्लिकेशन कोड लिखें।

उन कारणों के लिए जो थोड़े समय में स्पष्ट हो जाएंगे, आइए अपने में एक संपादन कार्यक्षमता जोड़कर प्रारंभ करें /list पृष्ठ। हम प्रत्येक टूडू के लिए यह दूसरी तालिका पंक्ति जोड़ेंगे:

import { enhance } from "$app/forms";
<tr> <td colspan="4"> <form use:enhance method="post" action="?/editTodo"> <input name="id" value="{t.id}" type="hidden" /> <input name="title" value="{t.title}" /> <button>Save</button> </form> </td>
</tr>

और, ज़ाहिर है, हमें अपने लिए एक फॉर्म एक्शन जोड़ना होगा /list पृष्ठ। क्रियाएं केवल अंदर जा सकती हैं .server पृष्ठ, इसलिए हम एक जोड़ देंगे +page.server.js हमारे में /list फ़ोल्डर। (हाँ एक +page.server.js फ़ाइल a के बगल में सह-अस्तित्व में हो सकती है +page.js फ़ाइल।)

import { getTodo, updateTodo, wait } from "$lib/data/todoData"; export const actions = { async editTodo({ request, cookies }) { const formData = await request.formData(); const id = formData.get("id"); const newTitle = formData.get("title"); await wait(250); updateTodo(id, newTitle); cookies.set("todos-cache", +new Date(), { path: "/", httpOnly: false }); },
};

हम फॉर्म डेटा को हड़प रहे हैं, देरी के लिए मजबूर कर रहे हैं, हमारे टूडू को अपडेट कर रहे हैं, और फिर, सबसे महत्वपूर्ण बात, हमारे कैशे बस्ट कुकी को साफ कर रहे हैं।

आइए इसे आज़माते हैं। अपने पृष्ठ को पुनः लोड करें, फिर किसी एक टू-डू आइटम को संपादित करें। आपको एक पल के बाद टेबल वैल्यू अपडेट देखना चाहिए। यदि आप DevToold में नेटवर्क टैब में देखते हैं, तो आपको एक फ़ेच दिखाई देगा /todos समापन बिंदु, जो आपका नया डेटा लौटाता है। सरल, और डिफ़ॉल्ट रूप से काम करता है।

डेटा सहेजा जा रहा है

तत्काल अपडेट

क्या होगा यदि हम अपने टू-डू आइटम को अपडेट करने के बाद होने वाली उस प्राप्ति से बचना चाहते हैं, और इसके बजाय, संशोधित आइटम को सीधे स्क्रीन पर अपडेट करें?

यह सिर्फ प्रदर्शन की बात नहीं है। यदि आप "पोस्ट" खोजते हैं और फिर सूची में किसी भी टू-डू आइटम से "पोस्ट" शब्द हटाते हैं, तो वे संपादन के बाद सूची से गायब हो जाएंगे क्योंकि वे अब उस पृष्ठ के खोज परिणामों में नहीं हैं। आप एक्साइटिंग टू-डू के लिए कुछ स्वादिष्ट एनिमेशन के साथ UX को बेहतर बना सकते हैं, लेकिन मान लें कि हम चाहते थे नहीं उस पृष्ठ के लोड फ़ंक्शन को फिर से चलाएं लेकिन फिर भी कैश साफ़ करें और संशोधित टू-डू अपडेट करें ताकि उपयोगकर्ता संपादन देख सके। SvelteKit इसे संभव बनाता है — आइए देखें कैसे!

सबसे पहले, आइए अपने लोडर में एक छोटा सा बदलाव करें। अपने टू-डू आइटम वापस करने के बजाय, आइए ए लौटाते हैं लिखने योग्य दुकान जिसमें हमारे कार्य-सूची शामिल हैं।

return { todos: writable(todos),
};

इससे पहले, हम पर अपने टू-डॉस एक्सेस कर रहे थे data प्रॉप, जिसका हमारा स्वामित्व नहीं है और जिसे हम अपडेट नहीं कर सकते। लेकिन Svelte हमें अपना डेटा उनके अपने स्टोर में वापस करने देता है (यह मानते हुए कि हम एक यूनिवर्सल लोडर का उपयोग कर रहे हैं, जो हम हैं)। हमें बस अपने लिए एक और ट्वीक बनाने की जरूरत है /list इस पृष्ठ पर ज़ूम कई वीडियो ट्यूटोरियल और अन्य साहायक साधन प्रदान करता है।

इसके अलावा:

{#each todos as t}

…हमें तब से ऐसा करने की आवश्यकता है todos खुद अब एक दुकान है.:

{#each $todos as t}

अब हमारा डाटा पहले की तरह लोड होता है। लेकिन फिर todos लिखने योग्य स्टोर है, हम इसे अपडेट कर सकते हैं।

सबसे पहले, आइए हमारे लिए एक फ़ंक्शन प्रदान करें use:enhance विशेषता:

<form use:enhance={executeSave} on:submit={runInvalidate} method="post" action="?/editTodo"
>

यह सबमिट करने से पहले चलेगा। आइए इसे आगे लिखें:

function executeSave({ data }) { const id = data.get("id"); const title = data.get("title"); return async () => { todos.update(list => list.map(todo => { if (todo.id == id) { return Object.assign({}, todo, { title }); } else { return todo; } }) ); };
}

यह फ़ंक्शन एक प्रदान करता है data हमारे प्रपत्र डेटा के साथ वस्तु। हम वापसी एक async फ़ंक्शन जो चलेगा बाद हमारा संपादन हो गया है। डॉक्स यह सब समझाएं, लेकिन ऐसा करने से, हम SvelteKit के डिफॉल्ट फॉर्म हैंडलिंग को बंद कर देते हैं जो हमारे लोडर को फिर से चलाता। ठीक यही हम चाहते हैं! (हम उस डिफ़ॉल्ट व्यवहार को आसानी से वापस पा सकते हैं, जैसा कि डॉक्स बताते हैं।)

अब हम फोन करते हैं update पर हमारे todos array क्योंकि यह एक स्टोर है। और वही जो है। एक टू-डू आइटम संपादित करने के बाद, हमारे परिवर्तन तुरंत दिखाई देते हैं और हमारा कैश साफ़ हो जाता है (पहले की तरह, क्योंकि हम अपने में एक नया कुकी मान सेट करते हैं editTodo फॉर्म एक्शन)। इसलिए, यदि हम खोज करते हैं और फिर इस पृष्ठ पर वापस नेविगेट करते हैं, तो हमें अपने लोडर से ताज़ा डेटा प्राप्त होगा, जो अपडेट किए गए किसी भी अपडेट किए गए टू-डू आइटम को सही ढंग से बाहर कर देगा।

तत्काल अद्यतन के लिए कोड गिटहब पर उपलब्ध है.

गहरा खोदना

हम केवल रूट लेआउट ही नहीं, किसी भी सर्वर लोड फ़ंक्शन (या सर्वर एक्शन) में कुकीज़ सेट कर सकते हैं। इसलिए, यदि कुछ डेटा का उपयोग केवल एक लेआउट या एक पृष्ठ के नीचे किया जाता है, तो आप उस कुकी मान को वहां सेट कर सकते हैं। इसके अलावा, अगर तुम हो नहीं ट्रिक करते हुए मैंने अभी-अभी ऑन-स्क्रीन डेटा को मैन्युअल रूप से अपडेट करते हुए दिखाया है, और इसके बजाय अपने लोडर को म्यूटेशन के बाद फिर से चलाना चाहते हैं, तो आप हमेशा उस लोड फ़ंक्शन में बिना किसी चेक के एक नया कुकी मान सेट कर सकते हैं isDataRequest. यह प्रारंभ में सेट होगा, और फिर जब भी आप एक सर्वर क्रिया चलाते हैं, तो पृष्ठ लेआउट स्वचालित रूप से अमान्य हो जाएगा और आपके लोडर को फिर से कॉल करेगा, आपके यूनिवर्सल लोडर को कॉल करने से पहले कैश बस्ट स्ट्रिंग को फिर से सेट करना होगा।

रीलोड फ़ंक्शन लिखना

आइए एक आखिरी सुविधा बनाकर समाप्त करें: एक पुनः लोड करें बटन। आइए उपयोगकर्ताओं को एक बटन दें जो कैश को साफ़ करेगा और फिर वर्तमान क्वेरी को पुनः लोड करेगा।

हम एक डर्ट सिंपल फॉर्म एक्शन जोड़ेंगे:

async reloadTodos({ cookies }) { cookies.set('todos-cache', +new Date(), { path: '/', httpOnly: false });
},

एक वास्तविक परियोजना में आप शायद एक ही कुकी को एक ही तरीके से कई स्थानों पर सेट करने के लिए एक ही कोड को कॉपी/पेस्ट नहीं करेंगे, लेकिन इस पोस्ट के लिए हम सरलता और पठनीयता के लिए अनुकूलन करेंगे।

अब इसमें पोस्ट करने के लिए एक फॉर्म बनाते हैं:

<form method="POST" action="?/reloadTodos" use:enhance> <button>Reload todos</button>
</form>

यह चलने लगा!

पुनः लोड करने के बाद यूआई।

हम इसे हो गया कह सकते हैं और आगे बढ़ सकते हैं, लेकिन आइए इस समाधान को थोड़ा सुधारें। विशेष रूप से, उपयोगकर्ता को यह बताने के लिए पृष्ठ पर प्रतिक्रिया दें कि पुनः लोड हो रहा है। साथ ही, डिफ़ॉल्ट रूप से, SvelteKit क्रियाएं अमान्य हो जाती हैं सब कुछ. वर्तमान पृष्ठ के पदानुक्रम में प्रत्येक लेआउट, पृष्ठ, आदि पुनः लोड होंगे। ऐसा कुछ डेटा हो सकता है जो रूट लेआउट में एक बार लोड हो जाता है जिसे हमें अमान्य या पुनः लोड करने की आवश्यकता नहीं है।

तो, आइए चीजों पर थोड़ा ध्यान दें, और जब हम इस फ़ंक्शन को कॉल करते हैं तो केवल हमारे टू-डॉस को पुनः लोड करें।

सबसे पहले, आइए एन्हांस करने के लिए एक फंक्शन पास करें:

<form method="POST" action="?/reloadTodos" use:enhance={reloadTodos}>
import { enhance } from "$app/forms";
import { invalidate } from "$app/navigation"; let reloading = false;
const reloadTodos = () => { reloading = true; return async () => { invalidate("reload:todos").then(() => { reloading = false; }); };
};

हम एक नया सेट कर रहे हैं reloading चर से true पर प्रारंभ इस क्रिया का। और फिर, सब कुछ अमान्य करने के डिफ़ॉल्ट व्यवहार को ओवरराइड करने के लिए, हम एक वापस करते हैं async समारोह। यह फ़ंक्शन तब चलेगा जब हमारी सर्वर क्रिया समाप्त हो जाएगी (जो अभी एक नई कुकी सेट करती है)।

इसके बिना async फ़ंक्शन लौटा, SvelteKit सब कुछ अमान्य कर देगा। चूंकि हम यह फ़ंक्शन प्रदान कर रहे हैं, यह कुछ भी अमान्य नहीं करेगा, इसलिए यह हमें बताना है कि क्या पुनः लोड करना है। हम इसके साथ करते हैं invalidate समारोह। हम इसे के मूल्य के साथ कहते हैं reload:todos. यह फ़ंक्शन एक वादा लौटाता है, जो अमान्यता पूर्ण होने पर हल करता है, जिस बिंदु पर हम सेट करते हैं reloading वापस करने के लिए false.

अंत में, हमें अपने लोडर को इस नए के साथ सिंक करना होगा reload:todos अमान्यता मूल्य। हम इसे अपने लोडर में depends समारोह:

export async function load({ fetch, url, setHeaders, depends }) { depends('reload:todos'); // rest is the same

और वही जो है। depends और invalidate अविश्वसनीय रूप से उपयोगी कार्य हैं। वह क्या अच्छा है invalidate हमारे द्वारा प्रदान किए गए मनमानी मूल्यों को ही नहीं लेता है जैसा हमने किया था। हम एक URL भी प्रदान कर सकते हैं, जिसे SvelteKit ट्रैक करेगा, और उस URL पर निर्भर किसी भी लोडर को अमान्य कर देगा। उस अंत तक, यदि आप सोच रहे हैं कि क्या हम कॉल को छोड़ सकते हैं depends और हमारे को अमान्य करें /api/todos समापन बिंदु पूरी तरह से, आप कर सकते हैं, लेकिन आपको प्रदान करना होगा सटीक यूआरएल, सहित search टर्म (और हमारा कैश वैल्यू)। इसलिए, आप या तो वर्तमान खोज के लिए URL को एक साथ रख सकते हैं, या पथ के नाम पर मिलान कर सकते हैं, जैसे:

invalidate(url => url.pathname == "/api/todos");

व्यक्तिगत रूप से, मुझे वह समाधान मिलता है जो उपयोग करता है depends अधिक स्पष्ट और सरल। लेकिन देखिए डॉक्स अधिक जानकारी के लिए, निश्चित रूप से, और अपने लिए निर्णय लें।

यदि आप रीलोड बटन को कार्य करते देखना चाहते हैं, तो इसके लिए कोड है रेपो की यह शाखा.

विचारों का विभाजन

यह एक लंबी पोस्ट थी, लेकिन उम्मीद है कि भारी नहीं होगी। SvelteKit का उपयोग करते समय हम विभिन्न तरीकों से डेटा को कैश कर सकते हैं। इसमें से अधिकांश केवल सही कैश, और कुकी मूल्यों को जोड़ने के लिए वेब प्लेटफॉर्म प्रिमिटिव का उपयोग करने का मामला था, जिसका ज्ञान केवल SvelteKit से परे, सामान्य रूप से वेब विकास में आपकी सेवा करेगा।

इसके अलावा, यह कुछ ऐसा है जो आप बिल्कुल करते हैं हर समय की जरूरत नहीं है. तर्कसंगत रूप से, आपको इस प्रकार की उन्नत सुविधाओं तक तभी पहुंचना चाहिए जब आप वास्तव में उनकी जरूरत है. यदि आपका डेटास्टोर तेजी से और कुशलता से डेटा की सेवा कर रहा है, और आप किसी भी प्रकार की स्केलिंग समस्याओं से नहीं निपट रहे हैं, तो आपके एप्लिकेशन कोड को अनावश्यक जटिलता के साथ फुलाए जाने का कोई मतलब नहीं है, जिन चीजों के बारे में हमने यहां बात की थी।

हमेशा की तरह, स्पष्ट, स्वच्छ, सरल कोड लिखें और आवश्यकता पड़ने पर अनुकूलित करें। इस पोस्ट का उद्देश्य आपको वे अनुकूलन उपकरण प्रदान करना था जब आपको वास्तव में उनकी आवश्यकता थी। मुझे उम्मीद है कि आपको मज़ा आया!

स्पॉट_आईएमजी

नवीनतम खुफिया

स्पॉट_आईएमजी

हमारे साथ चैट करें

नमस्ते! मैं आपकी कैसे मदद कर सकता हूँ?