Xlera8

SvelteKit-এ ক্যাশিং ডেটা

My পূর্ববর্তী পোস্ট SvelteKit এর একটি বিস্তৃত ওভারভিউ ছিল যেখানে আমরা দেখেছি এটি ওয়েব ডেভেলপমেন্টের জন্য কতটা দুর্দান্ত টুল। এই পোস্টটি আমরা সেখানে যা করেছি তা বন্ধ করে দেবে এবং প্রতিটি বিকাশকারীর প্রিয় বিষয়ের মধ্যে ডুব দেবে: ক্যাশিং. সুতরাং, যদি আপনি ইতিমধ্যে না করে থাকেন তবে আমার শেষ পোস্টটি পড়তে ভুলবেন না। এই পোস্টের জন্য কোড GitHub এ উপলব্ধ, পাশাপাশি হিসাবে একটি লাইভ ডেমো.

এই পোস্টটি সমস্ত ডেটা হ্যান্ডলিং সম্পর্কে। আমরা কিছু প্রাথমিক অনুসন্ধান কার্যকারিতা যোগ করব যা পৃষ্ঠার ক্যোয়ারী স্ট্রিং পরিবর্তন করবে (বিল্ট-ইন SvelteKit বৈশিষ্ট্যগুলি ব্যবহার করে), এবং পৃষ্ঠার লোডারকে পুনরায় ট্রিগার করবে। কিন্তু, শুধুমাত্র আমাদের (কাল্পনিক) ডাটাবেস পুনরায় অনুসন্ধান করার পরিবর্তে, আমরা কিছু ক্যাশিং যোগ করব যাতে পূর্বের অনুসন্ধানগুলি পুনরায় অনুসন্ধান করা (বা পিছনের বোতাম ব্যবহার করে) ক্যাশে থেকে দ্রুত পুনরুদ্ধার করা ডেটা দেখাবে। আমরা দেখব কিভাবে ক্যাশ করা ডেটা বৈধ থাকে তার দৈর্ঘ্য নিয়ন্ত্রণ করা যায় এবং আরও গুরুত্বপূর্ণভাবে, কীভাবে সমস্ত ক্যাশে করা মান ম্যানুয়ালি বাতিল করা যায়। কেকের উপর আইসিং হিসাবে, আমরা দেখব কিভাবে আমরা বর্তমান স্ক্রিনে, ক্লায়েন্ট-সাইডে, একটি মিউটেশনের পরে, ক্যাশে পরিষ্কার করার সময় ম্যানুয়ালি ডেটা আপডেট করতে পারি।

আমি সাধারণত যা লিখি তার চেয়ে এটি একটি দীর্ঘ, আরও কঠিন পোস্ট হবে কারণ আমরা কঠিন বিষয়গুলি কভার করছি। এই পোস্টটি মূলত আপনাকে দেখাবে কিভাবে জনপ্রিয় ডেটা ইউটিলিটিগুলির সাধারণ বৈশিষ্ট্যগুলি প্রয়োগ করতে হয় প্রতিক্রিয়া-কোয়েরি; কিন্তু একটি বাহ্যিক লাইব্রেরিতে টানার পরিবর্তে, আমরা শুধুমাত্র ওয়েব প্ল্যাটফর্ম এবং SvelteKit বৈশিষ্ট্যগুলি ব্যবহার করব৷

দুর্ভাগ্যবশত, ওয়েব প্ল্যাটফর্মের বৈশিষ্ট্যগুলি কিছুটা নিম্ন স্তরের, তাই আমরা আপনার অভ্যস্ত হওয়ার চেয়ে একটু বেশি কাজ করব। উল্টোটা হল আমাদের কোনো বাহ্যিক লাইব্রেরির প্রয়োজন হবে না, যা বান্ডিলের আকার সুন্দর এবং ছোট রাখতে সাহায্য করবে। অনুগ্রহ করে আমি যে পন্থাগুলি আপনাকে দেখাতে যাচ্ছি তা ব্যবহার করবেন না যদি না আপনার কাছে উপযুক্ত কারণ থাকে। ক্যাশিং ভুল করা সহজ, এবং আপনি দেখতে পাবেন, আপনার অ্যাপ্লিকেশন কোডের ফলে কিছুটা জটিলতা রয়েছে। আশা করি আপনার ডেটা স্টোর দ্রুত, এবং আপনার UI ঠিক আছে যা SvelteKit-কে যে কোনও পৃষ্ঠার জন্য প্রয়োজনীয় ডেটার অনুরোধ করার অনুমতি দেয়৷ যদি এটি হয়, এটি একা ছেড়ে দিন। সরলতা উপভোগ করুন। তবে এই পোস্টটি আপনাকে কিছু কৌশল দেখাবে যখন এটি হওয়া বন্ধ হবে।

প্রতিক্রিয়া-কোয়েরি কথা বলছি, এটা সবেমাত্র মুক্তি পেয়েছে Svelte জন্য! তাই যদি আপনি নিজেকে ম্যানুয়াল ক্যাশিং কৌশলগুলির উপর ঝুঁকে দেখতে পান অনেক, সেই প্রকল্পটি পরীক্ষা করে দেখতে ভুলবেন না এবং এটি সাহায্য করতে পারে কিনা তা দেখুন।

ঠিককরা

আমরা শুরু করার আগে, এর কয়েকটি ছোট পরিবর্তন করা যাক কোড আমরা আগে ছিল. এটি আমাদের কিছু অন্যান্য SvelteKit বৈশিষ্ট্যগুলি দেখার জন্য একটি অজুহাত দেবে এবং আরও গুরুত্বপূর্ণভাবে, সাফল্যের জন্য আমাদের সেট আপ করবে।

প্রথমে, আমাদের লোডার থেকে আমাদের ডেটা লোডিংকে ভিতরে নিয়ে যাওয়া যাক +page.server.js একটিতে API রুট. আমরা একটি তৈরি করব +server.js ফাইল ইন routes/api/todos, এবং তারপর একটি যোগ করুন 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="/bn/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));

মনে রাখবেন, এই পোস্টের জন্য সম্পূর্ণ কোড সবই গিটহাবে, যদি আপনি এটি উল্লেখ করতে হবে.

মৌলিক ক্যাশিং

আমাদের কিছু ক্যাশে যোগ করে শুরু করা যাক /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-এ ক্যাশে।

বিঃদ্রঃ নিশ্চিত হও আন-চেক চেকবক্স যা dev সরঞ্জামগুলিতে ক্যাশিং অক্ষম করে।

মনে রাখবেন, অ্যাপে আপনার প্রাথমিক নেভিগেশন যদি তালিকার পৃষ্ঠা হয়, তবে সেই অনুসন্ধানের ফলাফলগুলি অভ্যন্তরীণভাবে SvelteKit-এ ক্যাশে করা হবে, তাই সেই অনুসন্ধানে ফিরে আসার সময় DevTools-এ কিছু দেখার আশা করবেন না।

ক্যাশে কি, এবং কোথায়

আমাদের অ্যাপের প্রথম, সার্ভার-রেন্ডার করা লোড (অনুমান করে আমরা শুরু করি /list পৃষ্ঠা) সার্ভারে আনা হবে। SvelteKit সিরিয়ালাইজ করবে এবং আমাদের ক্লায়েন্টের কাছে এই ডেটা পাঠাবে। আরও কী, এটি পর্যবেক্ষণ করবে Cache-Control হেডার প্রতিক্রিয়াতে, এবং ক্যাশে উইন্ডোর মধ্যে সেই এন্ডপয়েন্ট কলের জন্য এই ক্যাশে করা ডেটা ব্যবহার করতে জানবে (যা আমরা উদাহরণে 60 সেকেন্ডে সেট করেছি)।

সেই প্রাথমিক লোডের পরে, আপনি যখন পৃষ্ঠায় অনুসন্ধান শুরু করেন, তখন আপনি আপনার ব্রাউজার থেকে নেটওয়ার্ক অনুরোধগুলি দেখতে পাবেন৷ /api/todos তালিকা আপনি ইতিমধ্যেই অনুসন্ধান করেছেন এমন জিনিসগুলি অনুসন্ধান করার সাথে সাথে (শেষ 60 সেকেন্ডের মধ্যে), প্রতিক্রিয়াগুলি ক্যাশে হওয়ার পর থেকে অবিলম্বে লোড হওয়া উচিত।

এই পদ্ধতির সাথে যা বিশেষভাবে দুর্দান্ত তা হল, যেহেতু এটি ব্রাউজারের নেটিভ ক্যাশিংয়ের মাধ্যমে ক্যাশে করা হচ্ছে, তাই এই কলগুলি (আপনি কীভাবে ক্যাশে বাস্টিং পরিচালনা করব তার উপর নির্ভর করে) আপনি পৃষ্ঠাটি পুনরায় লোড করলেও ক্যাশে চালিয়ে যেতে পারে (এর বিপরীতে প্রারম্ভিক সার্ভার-সাইড লোড, যা সর্বদা শেষ পয়েন্টকে ফ্রেশ বলে, এমনকি যদি এটি শেষ 60 সেকেন্ডের মধ্যে করে থাকে)।

স্পষ্টতই ডেটা যে কোনও সময় পরিবর্তন হতে পারে, তাই আমাদের এই ক্যাশেটি ম্যানুয়ালি পরিষ্কার করার একটি উপায় দরকার, যা আমরা পরবর্তীতে দেখব।

ক্যাশে অবৈধতা

এই মুহূর্তে, ডেটা 60 সেকেন্ডের জন্য ক্যাশে করা হবে। যাই হোক না কেন, এক মিনিট পর, আমাদের ডেটাস্টোর থেকে তাজা ডেটা তোলা হবে। আপনি একটি ছোট বা দীর্ঘ সময়কাল চাইতে পারেন, কিন্তু আপনি যদি কিছু ডেটা পরিবর্তন করেন এবং আপনার ক্যাশে অবিলম্বে সাফ করতে চান যাতে আপনার পরবর্তী ক্যোয়ারী আপ টু ডেট হতে পারে তাহলে কি হবে? আমরা আমাদের নতুন ইউআরএলে যে ইউআরএলটি পাঠাই তাতে একটি ক্যোয়ারী-বাস্টিং মান যোগ করে এটি সমাধান করব /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; অন্যথায়, আমরা ইতিমধ্যে সেখানে যা আছে তা পাঠাই।

সার্জারির 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 অ্যারে যেহেতু এটি একটি দোকান। এবং সেটাই। একটি করণীয় আইটেম সম্পাদনা করার পরে, আমাদের পরিবর্তনগুলি অবিলম্বে প্রদর্শিত হয় এবং আমাদের ক্যাশে সাফ হয়ে যায় (আগের মতো, যেহেতু আমরা আমাদের মধ্যে একটি নতুন কুকি মান সেট করেছি editTodo ফর্ম কর্ম)। সুতরাং, যদি আমরা অনুসন্ধান করি এবং তারপরে এই পৃষ্ঠায় ফিরে যান, আমরা আমাদের লোডার থেকে নতুন ডেটা পাব, যা আপডেট করা হয়েছে এমন যেকোনো আপডেট করা করণীয় আইটেমকে সঠিকভাবে বাদ দেবে।

অবিলম্বে আপডেটের জন্য কোড GitHub এ উপলব্ধ.

গভীরে খনন

আমরা যেকোন সার্ভার লোড ফাংশনে (বা সার্ভার অ্যাকশন) কুকি সেট করতে পারি, শুধু রুট লেআউট নয়। সুতরাং, যদি কিছু ডেটা শুধুমাত্র একটি একক লেআউট বা এমনকি একটি একক পৃষ্ঠার নীচে ব্যবহার করা হয়, আপনি সেখানে সেই কুকি মান সেট করতে পারেন। তাছাড়া, যদি আপনি হন না কৌশলটি করছি যা আমি ম্যানুয়ালি অন-স্ক্রীন ডেটা আপডেট করার জন্য দেখিয়েছি, এবং পরিবর্তে আপনার লোডারটি একটি মিউটেশনের পরে পুনরায় চালানোর জন্য চাই, তাহলে আপনি সর্বদা সেই লোড ফাংশনে কোনও পরীক্ষা ছাড়াই একটি নতুন কুকি মান সেট করতে পারেন 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>

ওই কাজগুলো!

পুনরায় লোড করার পরে UI।

আমরা এটিকে সম্পন্ন বলতে পারি এবং এগিয়ে যেতে পারি, তবে আসুন এই সমাধানটিকে কিছুটা উন্নত করি। বিশেষত, ব্যবহারকারীকে পুনরায় লোড হচ্ছে তা জানাতে পৃষ্ঠায় প্রতিক্রিয়া প্রদান করা যাক। এছাড়াও, ডিফল্টরূপে, 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 শেষবিন্দু সম্পূর্ণভাবে, আপনি করতে পারেন, কিন্তু আপনাকে প্রদান করতে হবে সঠিক URL সহ search মেয়াদ (এবং আমাদের ক্যাশে মান)। সুতরাং, আপনি বর্তমান অনুসন্ধানের জন্য URL একসাথে রাখতে পারেন, অথবা পথের নামের সাথে মিল করতে পারেন, যেমন:

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

ব্যক্তিগতভাবে, আমি ব্যবহার করে এমন সমাধান খুঁজে পাই depends আরো স্পষ্ট এবং সহজ। কিন্তু দেখুন ডক্স আরও তথ্যের জন্য, অবশ্যই, এবং নিজের জন্য সিদ্ধান্ত নিন।

আপনি যদি পুনরায় লোড বোতামটি কার্যকর দেখতে চান তবে এটির কোডটি রয়েছে৷ রেপো এই শাখা.

বিভাজন চিন্তাভাবনা

এটি একটি দীর্ঘ পোস্ট ছিল, কিন্তু আশা করি অপ্রতিরোধ্য না. SvelteKit ব্যবহার করার সময় আমরা বিভিন্ন উপায়ে ডেটা ক্যাশে করতে পারি। এর বেশিরভাগই ছিল সঠিক ক্যাশে এবং কুকির মানগুলি যোগ করার জন্য ওয়েব প্ল্যাটফর্মের আদিম ব্যবহার করার বিষয়, যার জ্ঞান শুধুমাত্র SvelteKit এর বাইরেও সাধারণভাবে ওয়েব ডেভেলপমেন্টে আপনাকে পরিবেশন করবে।

তাছাড়া, এই আপনি একেবারে কিছু সব সময় প্রয়োজন নেই. তর্কাতীতভাবে, আপনি শুধুমাত্র যখন আপনি উন্নত বৈশিষ্ট্য এই সাজানোর জন্য পৌঁছানো উচিত আসলে তাদের প্রয়োজন. যদি আপনার ডেটাস্টোর দ্রুত এবং দক্ষতার সাথে ডেটা পরিবেশন করে, এবং আপনি কোনও ধরণের স্কেলিং সমস্যা মোকাবেলা না করেন, তাহলে আমরা এখানে যে জিনিসগুলি নিয়ে কথা বলেছি তা করার জন্য আপনার অ্যাপ্লিকেশন কোডটি অপ্রয়োজনীয় জটিলতার সাথে ফুলিয়ে তোলার কোন মানে নেই।

বরাবরের মতো, পরিষ্কার, পরিষ্কার, সহজ কোড লিখুন এবং প্রয়োজনে অপ্টিমাইজ করুন। এই পোস্টের উদ্দেশ্য ছিল আপনাকে সেই অপ্টিমাইজেশান টুলগুলি প্রদান করা যখন আপনার সত্যিকারের সেগুলি প্রয়োজন৷ আমি আশা করি তুমি এটা উপভোগ করেছ!

আমাদের সাথে খোস গল্প কর

হাই সেখানে! আপনাকে কিভাবে সাহায্য করতে পারি?