Haunted — это библиотека для создания реактивных веб-компонентов на основе веб-стандартов, использующая Hooks, аналогичные React. Одним из важных аспектов работы с компонентами является эффективное управление данными, которое напрямую влияет на производительность. Кэширование позволяет хранить данные между рендерами и предотвращает избыточные вычисления или сетевые запросы.
Основной инструмент кэширования в Haunted — это сочетание
useState,
useEffect и
useMemo.
useState используется для хранения текущего состояния
данных.useEffect позволяет реагировать на изменения
зависимостей и обновлять состояние при необходимости.useMemo создаёт мемоизированные
значения, которые пересчитываются только при изменении
зависимостей.Пример кэширования вычисленного значения:
import { html, component, useState, useMemo } from 'haunted';
function FibonacciComponent() {
const [n, setN] = useState(10);
const fib = useMemo(() => {
const computeFib = (num) => {
if (num <= 1) return num;
return computeFib(num - 1) + computeFib(num - 2);
};
return computeFib(n);
}, [n]);
return html`
<div>
<p>Fibonacci(${n}) = ${fib}</p>
<input type="number" @input=${e => setN(Number(e.target.value))} value=${n}>
</div>
`;
}
customElements.define('fibonacci-component', component(FibonacciComponent));
В этом примере вычисление Фибоначчи кэшируется, и
функция computeFib вызывается только при изменении
n. Без useMemo каждое обновление компонента
инициировало бы повторный расчёт.
Для работы с API или любыми асинхронными источниками данных важно
избежать повторных запросов при каждом рендере. В Haunted кэширование
асинхронных данных обычно строится на базе
useState и
useEffect, иногда в сочетании с
глобальными структурами, такими как Map или WeakMap.
Пример кэширования данных с API:
import { html, component, useState, useEffect } from 'haunted';
const cache = new Map();
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
useEffect(() => {
if (cache.has(userId)) {
setUser(cache.get(userId));
return;
}
fetch(`https://api.example.com/users/${userId}`)
.then(res => res.json())
.then(data => {
cache.set(userId, data);
setUser(data);
});
}, [userId]);
return html`
<div>
${user ? html`<h2>${user.name}</h2>` : html`<p>Loading...</p>`}
</div>
`;
}
customElements.define('user-profile', component(UserProfile));
В этом случае Map выступает глобальным кэшем, который сохраняет уже загруженные данные, что уменьшает нагрузку на сеть и ускоряет рендеринг компонента.
useState и подходит для данных, которые не нужны другим
компонентам.Преимущество глобального кэша — централизованное управление данными и минимизация повторных запросов. Недостаток — возможные утечки памяти, если не очищать устаревшие данные.
Haunted ререндерит компонент каждый раз при изменении состояния. Чтобы избежать лишних вычислений:
useMemo.Пример оптимизации:
import { html, component, useState, useCallback } from 'haunted';
function Counter() {
const [count, setCount] = useState(0);
const increment = useCallback(() => setCount(c => c + 1), []);
return html`
<button @click=${increment}>Increment: ${count}</button>
`;
}
customElements.define('counter-button', component(Counter));
Использование useCallback предотвращает
создание новой функции на каждом рендере и позволяет
компонентам-потомкам, зависящим от этого колбэка, избегать лишних
обновлений.
Если в состоянии хранятся объекты или массивы, важно создавать новые экземпляры только при необходимости, иначе Haunted будет воспринимать их как новые и ререндерить компонент.
Пример с массивом:
import { html, component, useState, useMemo } from 'haunted';
function ItemsList({ items }) {
const sortedItems = useMemo(() => {
return [...items].sort((a, b) => a.name.localeCompare(b.name));
}, [items]);
return html`
<ul>
${sortedItems.map(item => html`<li>${item.name}</li>`)}
</ul>
`;
}
customElements.define('items-list', component(ItemsList));
Копирование массива перед сортировкой и
использование useMemo предотвращают ненужные повторные
рендеры, даже если родительский компонент обновляется.
useMemo.useCallback.useEffect и useMemo
— неправильное указание может привести к бесконечным рендерам или
устаревшим данным.WeakMap) это делается автоматически, для Map и массивов —
вручную.Кэширование данных в Haunted позволяет значительно ускорить работу приложения, минимизировать сетевые запросы и снизить нагрузку на браузер, при этом сохраняя реактивность компонентов.