Что такое мемоизация
Что проверяют
Понимаете ли вы, что это кэш по аргументам, и знаете ли условия применимости и цену.
Как отвечать
Мемоизация это кэширование результата функции по её аргументам: при повторном вызове с теми же входами результат берётся из кэша, а не считается заново.
function memoize(fn) {
const cache = new Map();
return (...args) => {
const key = JSON.stringify(args);
if (!cache.has(key)) cache.set(key, fn(...args));
return cache.get(key);
};
}Обязательное условие: функция должна быть чистой. Если результат зависит от времени, случайности или внешнего состояния, кэш начнёт отдавать неверное. Второе условие: вычисление должно быть дороже, чем поиск в кэше, иначе выигрыша нет.
Цена и подводные камни:
- память: кэш растёт неограниченно. Для долгоживущих функций нужна стратегия вытеснения (по размеру, по времени) или
WeakMap, когда ключ это объект; - ключ:
JSON.stringifyот объекта чувствителен к порядку полей и не сериализует функции иundefined. Для одного простого аргумента лучшеMapбез преобразования.
В React мемоизация встречается в трёх видах, и их путают:
useMemoзапоминает значение между рендерами по массиву зависимостей;useCallbackзапоминает функцию, чтобы стабильная ссылка не ломала мемоизацию дочернего компонента;React.memoпропускает перерисовку компонента, если пропсы не изменились поверхностным сравнением.
Важные оговорки: useMemo не гарантия, React вправе сбросить кэш; у самой мемоизации есть накладные расходы, поэтому оборачивать каждое выражение вредно; и React.memo бесполезен, если в компонент передают объектный литерал или функцию, создаваемые заново при каждом рендере. В React 19 компилятор берёт значительную часть этой работы на себя.
Где спотыкаются
Мемоизируют нечистую функцию.
Оборачивают в useMemo всё подряд, включая дешёвые вычисления.
Ставят React.memo, но передают внутрь новый объект каждый рендер.
Не думают о росте кэша в долгоживущем процессе.