> Какие техники кэширования существуют в React (React)
Уровень: senior · Роль: frontend · Категория: Технические вопросы
Компании: Spotware
Стек: React
> Пример ответа
Короткий ответ
В React кэширование применяется для оптимизации производительности: React.memo мемоизирует компонент, useMemo кэширует вычисления, useCallback - функции. Для данных используются React Query, SWR, Redux Toolkit с createEntityAdapter. На сервере - React Server Components и кэш Next.js. Ключевой trade-off: скорость vs актуальность данных и потребление памяти.
Подробное объяснение
Кэширование в React решает две задачи: предотвращение лишних ререндеров и сокращение повторных вычислений или запросов.
На уровне компонентов:
React.memo- поверхностное сравнение пропсов, пропускает ререндер, если пропсы не изменились. Полезно для тяжелых компонентов, но не для всех - сравнение тоже стоит ресурсов.useMemo- кэширует результат функции между рендерами, пока не изменятся зависимости. Используется для дорогих вычислений (фильтрация, сортировка больших массивов).useCallback- кэширует саму функцию, часто для передачи в memo-компоненты или в списки зависимостей эффектов.
На уровне данных:
- React Query (TanStack Query) - автоматическое кэширование ответов API с stale-while-revalidate стратегией, background refetch, инвалидация по ключам.
- SWR - похожий подход, но с фокусом на revalidation on focus и interval refetch.
- Redux Toolkit -
createEntityAdapterнормализует данные, аcreateAsyncThunkс кэшированием через middleware.
На уровне сервера:
- React Server Components - данные кэшируются на сервере, клиент получает готовый HTML, без повторных запросов.
- Next.js -
unstable_cache(илиcache()в App Router) для кэширования fetch-запросов, ISR (Incremental Static Regeneration) для страниц.
Продвинутые техники:
- Debounce и throttle для кэширования ввода (поиск, фильтры).
- LRU cache (Least Recently Used) для ограничения размера кэша - библиотеки типа
lru-cache. - Context splitting - разделение контекста на несколько, чтобы изменения в одной части не триггерили ререндер всей подписки.
На практике
Выбор техники зависит от сценария:
- Для статичных UI-элементов (иконки, хедер) -
React.memo. - Для вычислений на основе пропсов (например, отфильтрованный список) -
useMemo. - Для колбэков в memo-компонентах -
useCallback. - Для данных с сервера - React Query или SWR: они дают кэш с TTL, retry, optimistic updates.
- Для глобального состояния с частыми обновлениями - Redux Toolkit с нормализацией и селекторами (reselect).
- Для SSR/SSG - Next.js кэш на уровне фреймворка.
Важно: не мемоизировать всё подряд - это ухудшает читаемость и может увеличить потребление памяти. Кэширование должно быть обосновано профилированием (React DevTools Profiler, Chrome Performance tab).
Пример кода
JSX// React.memo для компонентаconst ExpensiveList = React.memo(({ items }) => {return items.map(item => <div key={item.id}>{item.name}</div>);});// useMemo для вычисленийfunction FilteredList({ items, filter }) {const filtered = useMemo(() => {return items.filter(item => item.name.includes(filter));}, [items, filter]);return <ExpensiveList items={filtered} />;}// useCallback для передачи в memo-компонентfunction Parent() {const handleClick = useCallback((id) => {console.log(id);}, []);return <Child onClick={handleClick} />;}// React Query с кэшированиемimport { useQuery } from '@tanstack/react-query';function UserProfile({ userId }) {const { data } = useQuery({queryKey: ['user', userId],queryFn: () => fetch(`/api/users/${userId}`).then(res => res.json()),staleTime: 5 * 60 * 1000, // 5 минут до устареванияcacheTime: 30 * 60 * 1000, // 30 минут в кэше});return <div>{data?.name}</div>;}
Как отвечать на собеседовании
Начни с краткого перечисления техник, затем выбери одну-две для углубленного объяснения. Покажи понимание trade-off: например, React.memo полезен только если компонент ререндерится с теми же пропсами, иначе сравнение пропсов - лишняя работа. Упомяни, что кэширование данных лучше выносить в библиотеки (React Query), а не писать вручную через useState + useEffect. Если спросят про серверный рендеринг - расскажи про React Server Components и кэш Next.js. Избегай абсолютизации: "всегда используй memo" - плохой совет.
Что проверяет интервьюер
- Понимание механизма ререндеров в React и как мемоизация на них влияет.
- Умение выбирать правильную технику под задачу, а не применять шаблонно.
- Знание современных библиотек для кэширования данных (React Query, SWR).
- Осознание компромиссов: память vs скорость, сложность кода vs производительность.
- Глубина: может ли кандидат объяснить, как работает stale-while-revalidate или LRU cache.
Типичные ошибки
- Мемоизация всего подряд без профилирования - ухудшает читаемость и может замедлить приложение из-за накладных расходов на сравнение.
- Использование
useMemoдля простых вычислений (например, конкатенация строк) - избыточно. - Забывание указать зависимости в
useMemo/useCallback- приводит к багам с устаревшими данными. - Применение
React.memoк компонентам с пропсами-функциями безuseCallback- мемоизация бесполезна. - Ручное кэширование данных через
useState+useEffectвместо библиотек - ведет к race conditions и дублированию кода. - Игнорирование инвалидации кэша - пользователи видят устаревшие данные.
> Похожие задачи по frontend
Как оптимизировать тяжелую функцию в React с помощью ленивой инициализации?
Почему хуки нельзя вызывать внутри условий и как это связано с жизненным циклом React-компонента
Как оптимизировать компонент Child, чтобы он не ререндерился при наборе текста в инпуте
Какие альтернативные способы установки фокуса в React без использования useEffect
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью