Кеширование является важной частью оптимизации веб-приложений, особенно при работе с компонентами и их состояниями. В Preact, как и в React, подход к кешированию ориентирован на минимизацию повторных вычислений, рендеров и сетевых запросов. Основная цель — уменьшить нагрузку на DOM и ускорить обновление интерфейса.
Ключевое отличие Preact от React заключается в компактности ядра и более легковесной системе обновления компонентов, что делает стратегию кеширования особенно значимой при крупных приложениях.
Кеширование компонентов Используется для
предотвращения повторного рендера компонентов с одинаковыми свойствами.
Основной инструмент — memo, который сохраняет результат
рендера и возвращает его при неизменных props.
import { h } from 'preact';
import { memo } from 'preact/compat';
const ExpensiveComponent = ({ data }) => {
console.log('Рендер ExpensiveComponent');
return <div>{data}</div>;
};
export default memo(ExpensiveComponent);
Здесь memo сравнивает предыдущие и новые props и
рендерит компонент только при их изменении. Можно использовать кастомную
функцию сравнения для более сложных случаев.
Кеширование функций и вычислений Для снижения
нагрузки на процессор при сложных вычислениях используется хук
useMemo.
import { h } from 'preact';
import { useMemo } from 'preact/hooks';
const ListComponent = ({ items }) => {
const sortedItems = useMemo(() => {
console.log('Сортировка элементов');
return items.sort((a, b) => a.value - b.value);
}, [items]);
return <ul>{sortedItems.map(item => <li key={item.id}>{item.value}</li>)}</ul>;
};
useMemo гарантирует, что сортировка выполняется только
при изменении items.
Кеширование событий и коллбеков Часто полезно
сохранять обработчики событий с помощью useCallback, чтобы
они не создавались заново при каждом рендере.
import { h } from 'preact';
import { useCallback, useState } from 'preact/hooks';
const Counter = () => {
const [count, setCount] = useState(0);
const increment = useCallback(() => setCount(c => c + 1), []);
return <button onCl ick={increment}>{count}</button>;
};
useCallback возвращает одну и ту же функцию между
рендерами, что уменьшает количество ненужных обновлений дочерних
компонентов.
Для приложений с большим количеством асинхронных запросов важно хранить данные в кеше, чтобы минимизировать сетевые вызовы.
useState и useEffect:import { h } from 'preact';
import { useState, useEffect } from 'preact/hooks';
const DataFetcher = ({ url }) => {
const [data, setData] = useState(null);
useEffect(() => {
let cancelled = false;
fetch(url)
.then(res => res.json())
.then(json => {
if (!cancelled) setData(json);
});
return () => { cancelled = true; };
}, [url]);
return <pre>{JSON.stringify(data, null, 2)}</pre>;
};
Stale-While-Revalidate Данные сразу отображаются из кеша, а фоновый запрос обновляет их. Позволяет уменьшить задержку рендера.
Cache-First Сначала проверяется кеш, и только при отсутствии данных выполняется сетевой запрос. Идеально для редко меняющихся данных.
Network-First Сначала делается запрос к серверу, а затем сохраняется результат в кеше. Полезно для критичных к актуальности данных компонентов.
Правильное использование атрибута key в списках
компонентов напрямую влияет на работу кеша Preact. Необходимо
использовать уникальные и стабильные значения для key,
чтобы Preact мог повторно использовать существующие DOM-узлы:
const List = ({ items }) => (
<ul>
{items.map(item => <li key={item.id}>{item.name}</li>)}
</ul>
);
Неправильные или меняющиеся ключи приводят к полному удалению и повторному созданию элементов, что снижает эффективность кеширования.
Компоненты можно загружать по требованию с помощью
lazy:
import { h, lazy, Suspense } from 'preact/compat';
const LazyComponent = lazy(() => import('./HeavyComponent'));
const App = () => (
<Suspense fallback={<div>Загрузка...</div>}>
<LazyComponent />
</Suspense>
);
Suspense позволяет показывать резервный контент, пока
компонент не загрузится, а последующие рендеры используют уже
кешированный модуль.
memo для тяжелых
компонентов, особенно в больших списках и при частых
обновлениях состояния.useMemo и useCallback
для дорогостоящих вычислений и коллбеков, чтобы минимизировать
лишние рендеры.Эффективное кеширование в Preact сочетает правильное управление состояниями, обработкой вычислений и оптимизацией сетевых данных, что позволяет достигать высокой производительности без избыточного кода и сложных структур.