Как мемоизация помогает оптимизировать вычисления в приложении
Что проверяют
Понимаете ли вы, что мемоизация это обмен памяти на время процессора, и знаете ли её цену. Во фронтенде разговор почти сразу уходит в React: когда нужны useMemo, useCallback и React.memo и почему расставлять их везде вредно.
Как отвечать
Суть: результат функции сохраняется по ключу из аргументов, и повторный вызов с теми же аргументами берёт его из кэша. Работает только для чистых функций: если результат зависит от времени, сети или внешнего состояния, кэш начнёт отдавать устаревшие данные.
Во фронтенде это несколько уровней:
- функция-мемоизатор: замыкание с
Map, ключ из аргументов. Наличие проверяют черезcache.has(key), а не по истинности значения, иначе результаты0,''иfalseникогда не закешируются; useMemo: кэш последнего вычисления внутри компонента, пересчёт при изменении зависимостей, которые сравниваются черезObject.is. Это подсказка, а не гарантия: React вправе сбросить кэш;useCallback: стабильная ссылка на функцию. Имеет смысл, когда её получает компонент подReact.memoили она стоит в зависимостях эффекта;React.memo: пропускает повторный рендер, если пропсы поверхностно равны;- селекторы:
createSelectorиз Reselect, чтобы производные данные из стора не пересчитывались и не давали новую ссылку на каждый вызов; - React Compiler: расставляет мемоизацию сам на этапе сборки, и в проектах с ним ручные
useMemoв основном не нужны.
Критерий, когда мемоизировать: вычисление реально дорогое (фильтрация тысяч строк, тяжёлый парсинг) или важна стабильность ссылки. Проверяется это профайлером в React DevTools, а не на глаз.
Где спотыкаются
Оборачивают в useMemo сложение двух чисел. Сравнение зависимостей и хранение кэша стоят дороже самого вычисления.
Передают в компонент под React.memo объект или стрелочную функцию, созданные прямо в JSX. Ссылка новая на каждый рендер, и мемоизация не срабатывает ни разу.
Делают кэш без ограничения размера или строят ключ через args.toString(). Первое превращается в утечку памяти, второе склеивает разные аргументы: все объекты дают одну и ту же строку, и функция возвращает чужой результат.