Preact — легковесный фреймворк для создания пользовательских интерфейсов на JavaScript, и его архитектура позволяет эффективно реализовывать offline-функциональность, минимизируя зависимость приложения от постоянного интернет-соединения. Offline-поддержка включает кеширование ресурсов, управление состоянием при отсутствии сети и синхронизацию данных после восстановления соединения.
Service Worker — ключевой инструмент для offline-приложений. Он работает как промежуточный слой между браузером и сетью, перехватывая запросы и отдавая кешированные ресурсы, если сеть недоступна.
Основные шаги интеграции Service Worker в Preact:
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/service-worker.js')
.then(() => console.log('Service Worker зарегистрирован'))
.catch(err => console.error('Ошибка регистрации:', err));
}
const CACHE_NAME = 'preact-app-cache-v1';
const urlsToCache = [
'/',
'/index.html',
'/bundle.js',
'/styles.css'
];
self.addEventListener('install', event => {
event.waitUntil(
caches.open(CACHE_NAME).then(cache => cache.addAll(urlsToCache))
);
});
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request).then(response => {
return response || fetch(event.request);
})
);
});
Ключевой момент: кеширование должно быть стратегическим. Например, критические ресурсы (HTML, JS, CSS) кешируются на долгий срок, а динамические данные (API-запросы) — с ограниченным сроком жизни.
Offline-приложения требуют сохранения пользовательских данных. Preact легко интегрируется с локальными хранилищами:
Пример использования IndexedDB:
import { openDB } from 'idb';
const dbPromise = openDB('preact-db', 1, {
upgrade(db) {
db.createObjectStore('todos', { keyPath: 'id', autoIncrement: true });
}
});
async function saveTodo(todo) {
const db = await dbPromise;
await db.put('todos', todo);
}
async function getTodos() {
const db = await dbPromise;
return await db.getAll('todos');
}
Преимущество IndexedDB — возможность хранить сложные структуры и синхронизировать их с сервером при восстановлении сети.
Preact использует Hooks и state management, что позволяет контролировать состояние приложения при отсутствии интернета.
Пример:
import { useState, useEffect } from 'preact/hooks';
function Todos() {
const [todos, setTodos] = useState([]);
const [online, setOnline] = useState(navigator.onLine);
useEffect(() => {
window.addEventListener('online', () => setOnline(true));
window.addEventListener('offline', () => setOnline(false));
getTodos().then(setTodos); // загрузка из IndexedDB
}, []);
return (
<div>
<p>Статус сети: {online ? 'online' : 'offline'}</p>
<ul>
{todos.map(todo => <li key={todo.id}>{todo.text}</li>)}
</ul>
</div>
);
}
Важный аспект — сохранение изменений локально при offline и их последующая синхронизация с сервером при подключении сети.
Пример Stale-While-Revalidate для API-запросов:
async function fetchTodos() {
const cache = await caches.open('api-cache');
const cachedResponse = await cache.match('/api/todos');
fetch('/api/todos').then(response => cache.put('/api/todos', response.clone()));
return cachedResponse ? cachedResponse.json() : fetch('/api/todos').then(res => res.json());
}
Offline-функциональность в Preact строится на комбинации Service Worker, локального хранилища и управления состоянием, что обеспечивает устойчивую работу приложения вне зависимости от стабильности интернет-соединения.