В веб-приложениях современного типа офлайн-режим играет критически важную роль. Он позволяет пользователю продолжать работу с приложением при отсутствии сети и обеспечивает корректную синхронизацию данных при восстановлении соединения. Inferno, как высокопроизводительный фреймворк для построения интерфейсов на JavaScript, предоставляет гибкие возможности для реализации таких сценариев благодаря своей легковесной архитектуре и высокой скорости обновления виртуального DOM.
Офлайн-режим в Inferno строится на нескольких ключевых компонентах: локальном хранилище данных, сервис-воркерах и контролируемых состояниях компонентов.
Для сохранения данных при отсутствии сети используется IndexedDB или LocalStorage. IndexedDB предпочтительнее для сложных структур данных и больших объемов, так как обеспечивает асинхронный доступ и транзакции.
Пример создания и использования IndexedDB в контексте Inferno:
const DB_NAME = 'appData';
const DB_VERSION = 1;
let db;
function openDatabase() {
const request = indexedDB.open(DB_NAME, DB_VERSION);
request.onupgradenee ded = (event) => {
db = event.target.result;
if (!db.objectStoreNames.contains('items')) {
db.createObjectStore('items', { keyPath: 'id', autoIncrement: true });
}
};
request.onsucc ess = (event) => {
db = event.target.result;
};
request.oner ror = (event) => {
console.error('Ошибка открытия базы данных:', event.target.error);
};
}
function saveItem(item) {
const transaction = db.transaction(['items'], 'readwrite');
const store = transaction.objectStore('items');
store.put(item);
}
В компонентах Inferno состояние должно быть тесно связано с локальной
базой данных. Использование useState или классового
состояния позволяет хранить данные в памяти до момента
синхронизации.
Сервис-воркеры позволяют перехватывать сетевые запросы и предоставлять кэшированные ответы при отсутствии соединения. Это ключевой элемент офлайн-поддержки.
Пример регистрации сервис-воркера:
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js')
.then(reg => console.log('Сервис-воркер зарегистрирован', reg))
.catch(err => console.error('Ошибка регистрации сервис-воркера', err));
}
Внутри sw.js можно реализовать стратегию кэширования
«Cache first» для статических ресурсов и «Network first» для данных,
синхронизируемых с сервером:
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request).then(cachedResponse => {
return cachedResponse || fetch(event.request).then(response => {
return caches.open('dynamic-cache').then(cache => {
cache.put(event.request.url, response.clone());
return response;
});
});
})
);
});
Когда соединение с сервером возобновляется, необходимо синхронизировать локальные изменения. Обычно используется очередь изменений, сохраненная в IndexedDB, и механизм отложенной отправки.
Пример реализации синхронизации:
async function syncChanges() {
const transaction = db.transaction(['items'], 'readonly');
const store = transaction.objectStore('items');
const allItems = await store.getAll();
for (const item of allItems) {
try {
const response = await fetch('/api/items', {
method: 'POST',
body: JSON.stringify(item),
headers: { 'Content-Type': 'application/json' }
});
if (response.ok) {
const deleteTransaction = db.transaction(['items'], 'readwrite');
deleteTransaction.objectStore('items').delete(item.id);
}
} catch (err) {
console.error('Ошибка синхронизации:', err);
}
}
}
window.addEventListener('online', syncChanges);
Ключевые моменты:
Компоненты Inferno должны быть чистыми и реактивными. Для офлайн-режима это означает:
setState или useState.Пример компонента:
import { Component } from 'inferno';
class ItemList extends Component {
state = { items: [] };
async componentDidMount() {
const items = await getAllItemsFromDB();
this.setState({ items });
window.addEventListener('online', this.syncChanges);
}
syncChanges = async () => {
await syncChanges();
const items = await getAllItemsFromDB();
this.setState({ items });
}
render() {
return (
<ul>
{this.state.items.map(item => <li key={item.id}>{item.name}</li>)}
</ul>
);
}
}
Inferno обеспечивает высокую скорость обновления интерфейса, что важно при работе с большим количеством офлайн-данных:
key) при рендеринге
списков, чтобы минимизировать количество перерисовок.Архитектура офлайн-приложений на Inferno строится вокруг трёх слоёв: локальное хранилище, сервис-воркер, компоненты UI с реактивным состоянием. Эта структура обеспечивает устойчивость приложения к отсутствию сети, корректную синхронизацию данных и высокую производительность интерфейса.