Slim.js — это легковесная JavaScript-библиотека для создания компонентного интерфейса, которая делает акцент на простоте реактивного программирования и управлении состоянием. Одной из ключевых задач при работе с внешними данными является эффективное кэширование запросов, позволяющее минимизировать нагрузку на сервер и ускорить отклик интерфейса.
Slim.js использует реактивные свойства (@state и
@prop) для управления состоянием компонента. Кэширование
запросов напрямую связано с этим механизмом:
import { Slim, html, state } from 'slim-js';
class UserList extends Slim {
@state users = [];
@state cache = {};
connectedCallback() {
super.connectedCallback();
this.loadUsers();
}
async loadUsers() {
const url = '/api/users';
if (this.cache[url]) {
this.users = this.cache[url];
return;
}
const response = await fetch(url);
const data = await response.json();
this.cache[url] = data;
this.users = data;
}
render() {
return html`
<ul>
${this.users.map(user => html`<li>${user.name}</li>`)}
</ul>
`;
}
}
customElements.define('user-list', UserList);
В этом примере объект cache служит
локальным хранилищем для результатов запросов. Перед выполнением
сетевого запроса происходит проверка, сохранены ли данные, что
предотвращает лишние вызовы fetch.
Чтобы кэш оставался актуальным, можно реализовать механизм временного хранения. Каждому запросу присваивается метка времени, после которой данные считаются устаревшими:
@state cache = {};
async loadUsers() {
const url = '/api/users';
const now = Date.now();
if (this.cache[url] && now - this.cache[url].timestamp < 60000) { // 60 секунд
this.users = this.cache[url].data;
return;
}
const response = await fetch(url);
const data = await response.json();
this.cache[url] = { data, timestamp: now };
this.users = data;
}
Ключевой момент — контроль времени жизни кэша (TTL). Это предотвращает использование устаревших данных и снижает риск отображения некорректной информации.
В сложных приложениях часто нужны динамические запросы с параметрами. Для этого используется система ключей, формируемых на основе URL и параметров запроса:
getCacheKey(url, params = {}) {
const query = new URLSearchParams(params).toString();
return `${url}?${query}`;
}
async loadUsers(params) {
const key = this.getCacheKey('/api/users', params);
if (this.cache[key]) {
this.users = this.cache[key];
return;
}
const response = await fetch(`/api/users?${new URLSearchParams(params)}`);
const data = await response.json();
this.cache[key] = data;
this.users = data;
}
Использование уникальных ключей для каждого запроса позволяет кэшировать разные варианты данных, не смешивая их между собой.
Slim.js автоматически отслеживает изменения реактивных свойств. После
обновления кэша достаточно присвоить новое значение @state,
чтобы интерфейс обновился:
this.users = this.cache[key]; // Интерфейс обновится автоматически
Это упрощает архитектуру приложения: нет необходимости вручную триггерить ререндер или управлять DOM.
Для сложных сценариев можно сочетать Slim.js с библиотеками кэширования, например localforage или IndexedDB, для сохранения данных между сессиями:
import localforage from 'localforage';
async loadUsers() {
const url = '/api/users';
const cached = await localforage.getItem(url);
if (cached) {
this.users = cached;
return;
}
const response = await fetch(url);
const data = await response.json();
await localforage.setItem(url, data);
this.users = data;
}
Такой подход расширяет возможности кэширования на уровне браузера и позволяет сохранять данные при перезагрузке страницы.
Частая ошибка при работе с асинхронными запросами — многократный вызов одного и того же запроса, если он ещё не завершён. Это можно решить с помощью промисов:
@state pendingRequests = {};
async loadUsers() {
const url = '/api/users';
if (this.cache[url]) {
this.users = this.cache[url];
return;
}
if (!this.pendingRequests[url]) {
this.pendingRequests[url] = fetch(url)
.then(res => res.json())
.then(data => {
this.cache[url] = data;
delete this.pendingRequests[url];
return data;
});
}
this.users = await this.pendingRequests[url];
}
Такой механизм гарантирует, что один запрос выполняется только один раз, даже если компонент несколько раз инициирует его одновременно.
Эффективное кэширование в Slim.js строится на нескольких принципах:
@state)pendingRequestsЭти подходы позволяют создавать высокопроизводительные интерфейсы, минимизировать сетевые обращения и сохранять чистую, реактивную архитектуру компонентов.