Bộ nhớ đệm dữ liệu trong SvelteKit

Bộ nhớ đệm dữ liệu trong SvelteKit

My trước bài là một cái nhìn tổng quan về SvelteKit, nơi chúng tôi thấy nó là một công cụ tuyệt vời như thế nào để phát triển web. Bài đăng này sẽ chia nhỏ những gì chúng tôi đã làm ở đó và đi sâu vào chủ đề yêu thích của mọi nhà phát triển: bộ nhớ đệm. Vì vậy, hãy nhớ đọc bài đăng cuối cùng của tôi nếu bạn chưa đọc. Mã cho bài viết này có sẵn trên GitHub, Cũng như một bản demo trực tiếp.

Bài đăng này là tất cả về xử lý dữ liệu. Chúng tôi sẽ thêm một số chức năng tìm kiếm cơ bản sẽ sửa đổi chuỗi truy vấn của trang (sử dụng các tính năng SvelteKit tích hợp sẵn) và kích hoạt lại trình tải của trang. Tuy nhiên, thay vì chỉ truy vấn lại cơ sở dữ liệu (tưởng tượng) của chúng tôi, chúng tôi sẽ thêm một số bộ nhớ đệm để việc tìm kiếm lại các tìm kiếm trước đó (hoặc sử dụng nút quay lại) sẽ nhanh chóng hiển thị dữ liệu đã truy xuất trước đó từ bộ đệm. Chúng ta sẽ xem xét cách kiểm soát khoảng thời gian mà dữ liệu được lưu trong bộ nhớ cache vẫn hợp lệ và quan trọng hơn là cách vô hiệu hóa tất cả các giá trị được lưu trong bộ nhớ cache theo cách thủ công. Khi bắt đầu làm bánh, chúng ta sẽ xem xét cách chúng ta có thể cập nhật dữ liệu theo cách thủ công trên màn hình hiện tại, phía máy khách, sau một đột biến, trong khi vẫn xóa bộ đệm.

Đây sẽ là một bài viết dài hơn, khó hơn hầu hết những gì tôi thường viết vì chúng ta đang đề cập đến các chủ đề khó hơn. Bài đăng này về cơ bản sẽ chỉ cho bạn cách triển khai các tính năng phổ biến của các tiện ích dữ liệu phổ biến như truy vấn phản ứng; nhưng thay vì sử dụng thư viện bên ngoài, chúng tôi sẽ chỉ sử dụng nền tảng web và các tính năng của SvelteKit.

Thật không may, các tính năng của nền tảng web ở mức thấp hơn một chút, vì vậy chúng tôi sẽ thực hiện nhiều công việc hơn một chút so với mức bạn có thể sử dụng. Ưu điểm là chúng tôi sẽ không cần bất kỳ thư viện bên ngoài nào, điều này sẽ giúp duy trì kích thước gói nhỏ và đẹp. Vui lòng không sử dụng các phương pháp tôi sắp chỉ cho bạn trừ khi bạn có lý do chính đáng. Bộ nhớ đệm rất dễ sai và như bạn sẽ thấy, có một chút phức tạp sẽ dẫn đến mã ứng dụng của bạn. Hy vọng rằng kho lưu trữ dữ liệu của bạn nhanh và giao diện người dùng của bạn ổn cho phép SvelteKit luôn yêu cầu dữ liệu cần thiết cho bất kỳ trang cụ thể nào. Nếu có, hãy để nó một mình. Tận hưởng sự đơn giản. Nhưng bài đăng này sẽ chỉ cho bạn một số thủ thuật khi điều đó không còn xảy ra nữa.

Nói về truy vấn phản ứng, nó vừa được phát hành cho Svelte! Vì vậy, nếu bạn thấy mình dựa vào các kỹ thuật lưu trữ thủ công rất nhiều, hãy chắc chắn kiểm tra dự án đó và xem nó có thể giúp ích gì không.

Thiết lập

Trước khi bắt đầu, hãy thực hiện một số thay đổi nhỏ đối với mã chúng tôi đã có trước đây. Điều này sẽ cho chúng tôi lý do để xem một số tính năng khác của SvelteKit và quan trọng hơn là chuẩn bị cho chúng tôi thành công.

Đầu tiên, hãy di chuyển tải dữ liệu của chúng tôi từ trình tải của chúng tôi vào +page.server.js đến một Tuyến API. Chúng tôi sẽ tạo một +server.js tập tin trong routes/api/todos, và sau đó thêm một GET chức năng. Điều này có nghĩa là bây giờ chúng ta sẽ có thể tìm nạp (sử dụng động từ GET mặc định) tới /api/todos đường dẫn. Chúng tôi sẽ thêm mã tải dữ liệu giống như trước đây.

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);
}

Tiếp theo, hãy sử dụng trình tải trang mà chúng tôi đã có và chỉ cần đổi tên tệp từ +page.server.js đến +page.js (Hoặc .ts nếu bạn đã dàn dựng dự án của mình để sử dụng TypeScript). Điều này thay đổi trình tải của chúng tôi thành trình tải “phổ quát” thay vì trình tải máy chủ. Tài liệu SvelteKit giải thích sự khác biệt, nhưng trình tải chung chạy trên cả máy chủ và cả máy khách. Một lợi thế cho chúng tôi là fetch gọi vào điểm cuối mới của chúng tôi sẽ chạy ngay từ trình duyệt của chúng tôi (sau lần tải đầu tiên), sử dụng trình duyệt gốc fetch chức năng. Chúng tôi sẽ thêm bộ nhớ đệm HTTP tiêu chuẩn một chút, nhưng bây giờ, tất cả những gì chúng tôi sẽ làm là gọi điểm cuối.

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, };
}

Bây giờ hãy thêm một biểu mẫu đơn giản vào /list :

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

Đúng, biểu mẫu có thể nhắm mục tiêu trực tiếp đến trình tải trang thông thường của chúng tôi. Bây giờ chúng ta có thể thêm cụm từ tìm kiếm vào hộp tìm kiếm, nhấn đăng ký hạng mục thivà cụm từ "tìm kiếm" sẽ được thêm vào chuỗi truy vấn của URL, chuỗi này sẽ chạy lại trình tải của chúng tôi và tìm kiếm các mục việc cần làm của chúng tôi.

Tìm kiếm hình thức
Bộ nhớ đệm dữ liệu trong SvelteKit

Chúng ta cũng hãy tăng độ trễ trong todoData.js tập tin trong /lib/data. Điều này sẽ giúp bạn dễ dàng biết khi nào dữ liệu được và không được lưu trong bộ nhớ cache khi chúng tôi làm việc qua bài đăng này.

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

Hãy nhớ rằng, mã đầy đủ cho bài đăng này là tất cả trên GitHub, nếu bạn cần tham khảo nó.

Bộ nhớ đệm cơ bản

Hãy bắt đầu bằng cách thêm một số bộ nhớ đệm vào /api/todos điểm cuối. Chúng tôi sẽ quay trở lại của chúng tôi +server.js tệp và thêm tiêu đề kiểm soát bộ đệm đầu tiên của chúng tôi.

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

… mà sẽ để lại toàn bộ chức năng trông như thế này:

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);
}

Chúng ta sẽ sớm xem xét việc vô hiệu hóa thủ công, nhưng tất cả chức năng này nói là lưu trữ các lệnh gọi API này trong 60 giây. Đặt cái này thành bất cứ thứ gì bạn muốnvà tùy thuộc vào trường hợp sử dụng của bạn, stale-while-revalidate cũng có thể đáng xem xét.

Và cứ như vậy, các truy vấn của chúng tôi được lưu vào bộ nhớ đệm.

Bộ đệm trong DevTools.
Bộ nhớ đệm dữ liệu trong SvelteKit

Chú thích chắc chắn rằng bạn bỏ kiểm tra hộp kiểm vô hiệu hóa bộ nhớ đệm trong các công cụ dành cho nhà phát triển.

Hãy nhớ rằng nếu điều hướng ban đầu của bạn trên ứng dụng là trang danh sách, thì các kết quả tìm kiếm đó sẽ được lưu trong bộ nhớ đệm nội bộ vào SvelteKit, vì vậy đừng mong đợi thấy bất kỳ điều gì trong DevTools khi quay lại tìm kiếm đó.

Bộ nhớ cache là gì và ở đâu

Tải ứng dụng đầu tiên do máy chủ kết xuất của chúng tôi (giả sử chúng tôi bắt đầu tại /list trang) sẽ được tìm nạp trên máy chủ. SvelteKit sẽ tuần tự hóa và gửi dữ liệu này xuống máy khách của chúng tôi. Hơn nữa, nó sẽ quan sát Cache-Control cú đội đầu trên phản hồi và sẽ biết cách sử dụng dữ liệu được lưu trong bộ nhớ cache này cho cuộc gọi điểm cuối đó trong cửa sổ bộ đệm (chúng tôi đặt thành 60 giây trong ví dụ đặt).

Sau lần tải đầu tiên đó, khi bạn bắt đầu tìm kiếm trên trang, bạn sẽ thấy các yêu cầu mạng từ trình duyệt của mình đến /api/todos danh sách. Khi bạn tìm kiếm những thứ bạn đã tìm kiếm (trong vòng 60 giây qua), các phản hồi sẽ tải ngay lập tức vì chúng được lưu vào bộ nhớ cache.

Điều đặc biệt thú vị với cách tiếp cận này là, vì đây là bộ nhớ đệm thông qua bộ nhớ đệm riêng của trình duyệt, nên các lệnh gọi này có thể (tùy thuộc vào cách bạn quản lý việc chặn truy xuất bộ đệm mà chúng ta sẽ xem xét) tiếp tục lưu vào bộ nhớ đệm ngay cả khi bạn tải lại trang (không giống như tải phía máy chủ ban đầu, luôn gọi điểm cuối mới, ngay cả khi điểm cuối thực hiện việc này trong vòng 60 giây qua).

Rõ ràng là dữ liệu có thể thay đổi bất cứ lúc nào, vì vậy chúng ta cần một cách để dọn sạch bộ nhớ cache này theo cách thủ công, điều mà chúng ta sẽ xem xét tiếp theo.

Vô hiệu bộ nhớ cache

Ngay bây giờ, dữ liệu sẽ được lưu vào bộ nhớ cache trong 60 giây. Không có vấn đề gì, sau một phút, dữ liệu mới sẽ được lấy từ kho dữ liệu của chúng tôi. Bạn có thể muốn một khoảng thời gian ngắn hơn hoặc dài hơn, nhưng điều gì xảy ra nếu bạn thay đổi một số dữ liệu và muốn xóa bộ nhớ đệm ngay lập tức để truy vấn tiếp theo của bạn được cập nhật? Chúng tôi sẽ giải quyết vấn đề này bằng cách thêm một giá trị chặn truy vấn vào URL mà chúng tôi gửi tới trang web mới của mình /todos điểm cuối.

Hãy lưu trữ giá trị chặn truy xuất bộ đệm này trong một cookie. Giá trị đó có thể được đặt trên máy chủ nhưng vẫn đọc được trên máy khách. Hãy xem xét một số mã mẫu.

Chúng ta có thể tạo một +layout.server.js tập tin ở thư mục gốc của chúng tôi routes thư mục. Điều này sẽ chạy khi khởi động ứng dụng và là nơi hoàn hảo để đặt giá trị cookie ban đầu.

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, };
}

Bạn có thể đã nhận thấy isDataRequest giá trị. Hãy nhớ rằng, bố cục sẽ chạy lại bất cứ lúc nào lệnh gọi mã máy khách invalidate()hoặc bất cứ khi nào chúng tôi chạy một hành động máy chủ (giả sử chúng tôi không tắt hành vi mặc định). isDataRequest cho biết những lần chạy lại đó và vì vậy chúng tôi chỉ đặt cookie nếu đó là false; nếu không, chúng tôi gửi theo những gì đã có.

Sản phẩm httpOnly: false lá cờ cũng rất quan trọng. Điều này cho phép mã máy khách của chúng tôi đọc các giá trị cookie này trong document.cookie. Đây thường là một mối lo ngại về bảo mật, nhưng trong trường hợp của chúng tôi, đây là những con số vô nghĩa cho phép chúng tôi lưu vào bộ nhớ cache hoặc phá bộ nhớ cache.

Đọc giá trị bộ đệm

Trình tải phổ quát của chúng tôi là cái gọi là /todos điểm cuối. Điều này chạy trên máy chủ hoặc máy khách và chúng tôi cần đọc giá trị bộ đệm mà chúng tôi vừa thiết lập bất kể chúng tôi ở đâu. Tương đối dễ dàng nếu chúng ta đang ở trên máy chủ: chúng ta có thể gọi await parent() để lấy dữ liệu từ bố cục gốc. Nhưng trên máy khách, chúng tôi sẽ cần sử dụng một số mã thô để phân tích cú pháp 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] ?? "";
};

May mắn thay, chúng tôi chỉ cần nó một lần.

Gửi giá trị bộ đệm

Nhưng bây giờ chúng ta cần phải gửi giá trị này cho chúng tôi /todos điểm cuối.

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') có một kiểm tra trong đó để xem chúng tôi có ở trên máy khách không (bằng cách kiểm tra loại tài liệu) và không trả lại gì nếu chúng tôi ở đó, tại thời điểm đó chúng tôi biết chúng tôi đang ở trên máy chủ. Sau đó, nó sử dụng giá trị từ bố cục của chúng tôi.

Phá bộ đệm

Nhưng làm thế nào chúng ta có thực sự cập nhật giá trị chặn truy xuất bộ đệm khi cần không? Vì nó được lưu trữ trong cookie nên chúng tôi có thể gọi nó như thế này từ bất kỳ hành động nào của máy chủ:

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

Việc thực hiện

Tất cả xuống dốc từ đây; chúng tôi đã hoàn thành công việc khó khăn. Chúng tôi đã đề cập đến các nguyên mẫu nền tảng web khác nhau mà chúng tôi cần, cũng như vị trí của chúng. Bây giờ, hãy vui vẻ và viết mã ứng dụng để liên kết tất cả lại với nhau.

Vì những lý do mà lát nữa sẽ trở nên rõ ràng, hãy bắt đầu bằng cách thêm chức năng chỉnh sửa vào /list trang. Chúng tôi sẽ thêm hàng bảng thứ hai này cho mỗi việc cần làm:

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>

Và, tất nhiên, chúng ta sẽ cần thêm một hành động biểu mẫu cho /list trang. Hành động chỉ có thể đi vào .server các trang, vì vậy chúng tôi sẽ thêm một +page.server.js trong /list thư mục. (Có, một +page.server.js tập tin có thể cùng tồn tại bên cạnh một +page.js tập tin.)

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 }); },
};

Chúng tôi đang lấy dữ liệu biểu mẫu, buộc trì hoãn, cập nhật việc cần làm của chúng tôi và sau đó, quan trọng nhất là xóa cookie truy xuất bộ nhớ cache của chúng tôi.

Hãy thử xem. Tải lại trang của bạn, sau đó chỉnh sửa một trong các mục việc cần làm. Bạn sẽ thấy bảng cập nhật giá trị sau một lúc. Nếu bạn nhìn vào tab Mạng trong DevToold, bạn sẽ thấy tìm nạp tới /todos điểm cuối, trả về dữ liệu mới của bạn. Đơn giản và hoạt động theo mặc định.

Tiết kiệm dữ liệu
Bộ nhớ đệm dữ liệu trong SvelteKit

Cập nhật ngay lập tức

Điều gì sẽ xảy ra nếu chúng ta muốn tránh việc tìm nạp đó xảy ra sau khi chúng ta cập nhật mục việc cần làm và thay vào đó, cập nhật mục đã sửa đổi ngay trên màn hình?

Đây không chỉ là vấn đề hiệu suất. Nếu bạn tìm kiếm “bài đăng” và sau đó xóa từ “bài đăng” khỏi bất kỳ mục việc cần làm nào trong danh sách, chúng sẽ biến mất khỏi danh sách sau khi chỉnh sửa vì chúng không còn trong kết quả tìm kiếm của trang đó nữa. Bạn có thể làm cho UX tốt hơn bằng một số hoạt ảnh trang nhã cho công việc cần làm sắp kết thúc, nhưng giả sử chúng tôi muốn không chạy lại chức năng tải của trang đó nhưng vẫn xóa bộ nhớ cache và cập nhật việc cần làm đã sửa đổi để người dùng có thể xem phần chỉnh sửa. SvelteKit biến điều đó thành hiện thực — hãy xem cách thực hiện!

Trước tiên, hãy thực hiện một thay đổi nhỏ đối với trình tải của chúng tôi. Thay vì trả lại các mục công việc của chúng tôi, hãy trả lại một cửa hàng có thể ghi chứa những việc cần làm của chúng tôi.

return { todos: writable(todos),
};

Trước đây, chúng tôi đã truy cập vào việc cần làm của mình trên data prop mà chúng tôi không sở hữu và không thể cập nhật. Nhưng Svelte cho phép chúng tôi trả lại dữ liệu của mình trong cửa hàng của riêng họ (giả sử chúng tôi đang sử dụng trình tải chung, chính là chúng tôi). Chúng ta chỉ cần thực hiện thêm một điều chỉnh nữa cho /list .

Thay vì điều này:

{#each todos as t}

…chúng ta cần làm điều này vì todos bản thân nó bây giờ là một cửa hàng.:

{#each $todos as t}

Bây giờ dữ liệu của chúng tôi tải như trước. Nhưng kể từ khi todos là một cửa hàng có thể ghi, chúng tôi có thể cập nhật nó.

Trước tiên, hãy cung cấp một chức năng cho use:enhance thuộc tính:

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

Điều này sẽ chạy trước khi gửi. Hãy viết điều đó tiếp theo:

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; } }) ); };
}

Chức năng này cung cấp một data đối tượng với dữ liệu biểu mẫu của chúng tôi. Chúng tôi trở lại một chức năng không đồng bộ sẽ chạy sau khi chỉnh sửa của chúng tôi được thực hiện. Các tài liệu giải thích tất cả những điều này, nhưng bằng cách này, chúng tôi tắt xử lý biểu mẫu mặc định của SvelteKit sẽ chạy lại trình tải của chúng tôi. Đây chính xác là những gì chúng tôi muốn! (Chúng tôi có thể dễ dàng lấy lại hành vi mặc định đó, như tài liệu giải thích.)

Bây giờ chúng tôi gọi update trên của chúng tôi todos mảng vì nó là một cửa hàng. Và đó là điều đó. Sau khi chỉnh sửa một mục việc cần làm, các thay đổi của chúng tôi sẽ hiển thị ngay lập tức và bộ nhớ cache của chúng tôi sẽ bị xóa (như trước đây, vì chúng tôi đã đặt một giá trị cookie mới trong editTodo hình thức hành động). Vì vậy, nếu chúng tôi tìm kiếm và sau đó điều hướng quay lại trang này, chúng tôi sẽ nhận được dữ liệu mới từ trình tải của mình, dữ liệu này sẽ loại trừ chính xác mọi mục việc cần làm được cập nhật đã được cập nhật.

Mã cho các bản cập nhật ngay lập tức có sẵn tại GitHub.

Đào sâu hơn

Chúng tôi có thể đặt cookie trong bất kỳ chức năng tải máy chủ nào (hoặc hành động của máy chủ), không chỉ bố cục gốc. Vì vậy, nếu một số dữ liệu chỉ được sử dụng bên dưới một bố cục hoặc thậm chí một trang, bạn có thể đặt giá trị cookie đó ở đó. Hơn nữa, nếu bạn đang không thực hiện mẹo mà tôi vừa trình bày là cập nhật dữ liệu trên màn hình theo cách thủ công và thay vào đó, muốn trình tải của bạn chạy lại sau một đột biến, thì bạn luôn có thể đặt giá trị cookie mới ngay trong chức năng tải đó mà không cần kiểm tra lại isDataRequest. Nó sẽ được đặt ban đầu và sau đó bất cứ khi nào bạn chạy một hành động máy chủ, bố cục trang sẽ tự động vô hiệu hóa và gọi lại trình tải của bạn, đặt lại chuỗi ngắt bộ đệm trước khi trình tải chung của bạn được gọi.

Viết chức năng tải lại

Hãy kết thúc bằng cách xây dựng một tính năng cuối cùng: nút tải lại. Hãy cung cấp cho người dùng một nút sẽ xóa bộ nhớ đệm và sau đó tải lại truy vấn hiện tại.

Chúng tôi sẽ thêm một hành động biểu mẫu đơn giản:

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

Trong một dự án thực tế, có thể bạn sẽ không sao chép/dán cùng một mã để đặt cùng một cookie theo cùng một cách ở nhiều nơi, nhưng đối với bài đăng này, chúng tôi sẽ tối ưu hóa để đơn giản và dễ đọc.

Bây giờ hãy tạo một biểu mẫu để đăng lên đó:

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

Điều đó hoạt động!

Giao diện người dùng sau khi tải lại.
Bộ nhớ đệm dữ liệu trong SvelteKit

Chúng ta có thể gọi điều này là xong và tiếp tục, nhưng hãy cải thiện giải pháp này một chút. Cụ thể, hãy cung cấp phản hồi trên trang để cho người dùng biết quá trình tải lại đang diễn ra. Ngoài ra, theo mặc định, các hành động SvelteKit không hợp lệ tất cả mọi thứ. Mọi bố cục, trang, v.v. trong hệ thống phân cấp của trang hiện tại sẽ tải lại. Có thể có một số dữ liệu được tải một lần trong bố cục gốc mà chúng tôi không cần phải vô hiệu hóa hoặc tải lại.

Vì vậy, hãy tập trung vào mọi thứ một chút và chỉ tải lại những việc cần làm khi chúng ta gọi chức năng này.

Đầu tiên, hãy vượt qua một chức năng để tăng cường:

<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; }); };
};

Chúng tôi đang thiết lập một cái mới reloading biến thành true tại Bắt đầu của hành động này. Và sau đó, để ghi đè hành vi mặc định làm mất hiệu lực mọi thứ, chúng tôi trả về một async chức năng. Chức năng này sẽ chạy khi hành động máy chủ của chúng tôi kết thúc (chỉ đặt cookie mới).

Không có cái này async chức năng được trả về, SvelteKit sẽ làm mất hiệu lực mọi thứ. Vì chúng tôi đang cung cấp chức năng này nên nó sẽ không làm mất hiệu lực gì cả, vì vậy chúng tôi phải cho nó biết cần tải lại cái gì là tùy thuộc vào chúng tôi. Chúng tôi làm điều này với invalidate chức năng. Chúng tôi gọi nó với một giá trị của reload:todos. Hàm này trả về một lời hứa, lời hứa này sẽ giải quyết khi quá trình vô hiệu hóa hoàn tất, tại thời điểm đó chúng ta đặt reloading trở lại false.

Cuối cùng, chúng ta cần đồng bộ hóa trình tải của mình với cái mới này reload:todos giá trị vô hiệu. Chúng tôi làm điều đó trong trình tải của chúng tôi với depends chức năng:

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

Và đó là điều đó. dependsinvalidate là những chức năng cực kỳ hữu ích. Điều đó thật tuyệt invalidate không chỉ nhận các giá trị tùy ý mà chúng tôi cung cấp như chúng tôi đã làm. Chúng tôi cũng có thể cung cấp một URL mà SvelteKit sẽ theo dõi và vô hiệu hóa bất kỳ trình tải nào phụ thuộc vào URL đó. Cuối cùng, nếu bạn đang tự hỏi liệu chúng ta có thể bỏ qua cuộc gọi đến depends và làm mất hiệu lực của chúng tôi /api/todos điểm cuối hoàn toàn, bạn có thể, nhưng bạn phải cung cấp chính xác URL, bao gồm cả search hạn (và giá trị bộ đệm của chúng tôi). Vì vậy, bạn có thể kết hợp URL cho tìm kiếm hiện tại hoặc khớp với tên đường dẫn, như sau:

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

Cá nhân, tôi thấy giải pháp sử dụng depends rõ ràng và đơn giản hơn. Nhưng hãy xem tài liệu để biết thêm thông tin, tất nhiên, và quyết định cho chính mình.

Nếu bạn muốn xem nút tải lại đang hoạt động, mã của nó nằm trong chi nhánh này của repo.

Chia tay suy nghĩ

Đây là một bài viết dài, nhưng hy vọng không áp đảo. Chúng tôi nghiên cứu nhiều cách khác nhau để có thể lưu trữ dữ liệu trong bộ đệm khi sử dụng SvelteKit. Phần lớn điều này chỉ là vấn đề sử dụng các nguyên mẫu của nền tảng web để thêm đúng bộ đệm và các giá trị cookie, kiến ​​thức về chúng sẽ phục vụ bạn trong quá trình phát triển web nói chung, ngoài SvelteKit.

Hơn nữa, đây là điều bạn hoàn toàn không cần tất cả thời gian. Có thể cho rằng, bạn chỉ nên sử dụng các loại tính năng nâng cao này khi bạn thực sự cần chúng. Nếu kho dữ liệu của bạn đang phục vụ dữ liệu một cách nhanh chóng và hiệu quả, đồng thời bạn không phải xử lý bất kỳ loại vấn đề nào về quy mô, thì không có lý do gì phải làm đầy mã ứng dụng của bạn với độ phức tạp không cần thiết để thực hiện những điều chúng tôi đã đề cập ở đây.

Như mọi khi, hãy viết mã rõ ràng, sạch sẽ, đơn giản và tối ưu hóa khi cần thiết. Mục đích của bài đăng này là cung cấp cho bạn những công cụ tối ưu hóa đó khi bạn thực sự cần chúng. Tôi hy vọng bạn thích nó!

Dấu thời gian:

Thêm từ Thủ thuật CSS