Background Sync — это механизм, позволяющий выполнять асинхронные задачи на сервере или в фоновом режиме, не блокируя основной поток выполнения приложения. В контексте Fresh, который строится поверх Deno и ориентирован на рендеринг на стороне сервера с использованием островов интерактивности, background sync играет ключевую роль в оптимизации производительности и поддержке реактивных интерфейсов.
В Fresh background sync используется для:
Background sync реализуется через асинхронные функции и обработчики событий, которые выполняются отдельно от основной логики рендеринга страницы. Ключевое отличие Fresh от традиционных SPA заключается в том, что серверная часть может управлять этими задачами нативно, без необходимости использования сторонних очередей.
Fresh использует маршруты (routes) для обработки
HTTP-запросов. Асинхронные операции можно выполнять внутри этих
маршрутов с помощью async функций.
// routes/api/sync.ts
import { HandlerContext } from "$fresh/server.ts";
export const handler = async (req: Request, ctx: HandlerContext) => {
if (req.method === "POST") {
const data = await req.json();
// Запуск фоновой задачи
queueBackgroundTask(data);
return new Response(JSON.stringify({ status: "queued" }), {
headers: { "Content-Type": "application/json" },
});
}
return new Response("Method Not Allowed", { status: 405 });
};
async function queueBackgroundTask(data: any) {
// Симуляция долгой задачи
setTimeout(() => {
console.log("Background task completed", data);
}, 5000);
}
В этом примере POST-запрос инициирует background task, которая
выполняется через setTimeout, не блокируя основной поток
сервера. В реальных приложениях вместо setTimeout
используются асинхронные операции с базой данных или внешними
API.
Острова (islands) в Fresh позволяют запускать
интерактивный JavaScript на клиенте, сохраняя при этом серверную
рендеринг-логики. Background sync может использоваться для отправки
данных с клиента на сервер, а сервер будет обрабатывать их в фоне.
// islands/SyncButton.tsx
import { useState } from "preact/hooks";
export default function SyncButton() {
const [status, setStatus] = useState("idle");
const handleClick = async () => {
setStatus("sending");
const res = await fetch("/api/sync", {
method: "POST",
body: JSON.stringify({ timestamp: Date.now() }),
headers: { "Content-Type": "application/json" },
});
const result = await res.json();
setStatus(result.status);
};
return (
<button onCl ick={handleClick}>
{status === "idle" ? "Sync Now" : status}
</button>
);
}
Ключевой момент: клиент инициирует синхронизацию, сервер принимает данные и запускает background task, обеспечивая асинхронную обработку без блокировки UI.
В Fresh background sync часто используется для операций с базой данных, которые могут занимать несколько секунд. Это позволяет поддерживать высокую отзывчивость интерфейса.
async function queueBackgroundTask(data: any) {
try {
// Имитация записи в базу данных
await fakeDatabaseInsert(data);
console.log("Data saved successfully");
} catch (error) {
console.error("Failed to save data:", error);
}
}
async function fakeDatabaseInsert(data: any) {
return new Promise((resolve) => setTimeout(resolve, 3000));
}
Использование такого подхода гарантирует, что запросы пользователя не будут задерживаться из-за медленных операций с базой данных.
При работе с background sync необходимо учитывать возможные ошибки и использовать механизмы повторной попытки:
async function queueBackgroundTask(data: any, retries = 3) {
try {
await fakeDatabaseInsert(data);
console.log("Data saved successfully");
} catch (error) {
if (retries > 0) {
console.log(`Retrying... attempts left: ${retries}`);
setTimeout(() => queueBackgroundTask(data, retries - 1), 2000);
} else {
console.error("Failed to save data after retries:", error);
}
}
}
Такой подход позволяет повысить надежность фоновых операций и избежать потери данных.
Для контроля работы background sync важно использовать логирование и мониторинг задач. В Fresh это можно делать через:
console.log и console.error для простого
логирования.Этот подход позволяет строить высокопроизводительные приложения с интерактивным интерфейсом и надежной синхронизацией данных между клиентом и сервером.