Hubo una etapa de mi vida como desarrollador donde pensaba que optimizar React significaba una cosa:
agregar useMemoy useCallback a todo lo que se moviera.
Si veía un cálculo, un array filtrado, una función…
“Memoízalo, por si acaso. No vaya a ser que React sufra.”
Y sí, React sufría… pero por culpa mía.
Este post es sobre cómo dejé de usar memoization como si fuera una aspirina para todo, y aprendí a aplicarla solo donde realmente aporta algo.
Si alguna vez te ha pasado que agregas useMemo y tu app va más lenta, créeme, estás en el lugar correcto.
🧩 La sobre-optimización que me estrelló contra la realidad
En uno de mis primeros proyectos grandes, tenía una lista enorme que se re-renderizaba seguido. Yo, muy confiado, pensé:
"¿Cuál es la mejor forma de optimizar React?
Fácil: memorizo todo 🥸☝🏼"
Y lo hice.
Cada función: useCallback.
Cada array: useMemo.
Cada cálculo: useMemootra vez.
Y practicamente así con todo ^_____^
Pero algo raro pasó:
la interfaz no iba más rápida… iba peor.
Se sentía "pesada", como si React estuviera peleando contra sí mismo.
Después recibí un feedback que me dejo pensando mucho:
"Leo… no puedes optimizar algo que no sabes si necesita optimización."
Y ahí me cayó el veinte.
⚙️ La revelación: memoization NO hace tu código más rápido
Yo pensaba que useMemo y useCallbackeran como un "modo turbo".
Pero la realidad es más simple y más dura:
useMemo evita un cálculo costoso
→ Solo si ese cálculo es realmente costoso.
useCallback evita que una función cambie de referencia
→ Solo si esa función se pasa a un componente memoizado.
Antes de eso, yo memorizaba filtros que tardaban 1 ms.
O funciones que ni siquiera pasaba como prop.
Era como ponerle cinturón de seguridad a una bicicleta estacionada.
🔍 useMemo en la vida real (no en el tutorial)
El propósito real:
const sortedList = useMemo(() => {
return heavySortFunction(list);
}, [list]);
Si heavySortFunction tarda 100 ms, esta línea te salva la vida.
Si tarda 0.5 ms, estás haciendo más trabajo del necesario.
💭 El momento en el que lo entendí
Un día estaba perfilando una app y me di cuenta de algo ridículo:
mi useMemo estaba tardando MÁS en comparar dependencias que el cálculo real que intentaba optimizar.
Ahí fue cuando dije: "Ok React, te escucho. Ya entendí."
🔧 useCallback: el primo que todos usan mal
Antes:
useCallback(() => console.log("hola"), [])
en todos lados.
Ahora sé que esta regla es real:
Si tu hijo no está memoizado, tu useCallback no sirve.
Ejemplo real en producción:
const handleClick = useCallback(() => {
doSomething();
}, []);
Si luego haces:
<Child onClick={handleClick} />
🚦 Cuándo SÍ usar memoization (sin culpa)
Sin drama, sin misterio:
✔️ 1. Cuando un cálculo es verdaderamente pesado
Filtro gigante, sort complejo, cálculos matemáticos, parseo.
✔️ 2. Cuando pasas funciones a un componente memoizado
Ese es el matrimonio perfecto:
React.memo + useCallback.
✔️ 3. Cuando tienes listas enormes o renders costosos
Si tienes 300 items en pantalla → ahí sí vale la pena.
🛑 Cuándo NO usar memoization (cerrando ciclos tóxicos)
Esto me cambió la vida:
❌ Cuando es “por si acaso”
La sobre-optimización es el cardio del sufrimiento.
❌ Cuando lo que optimizas es rápido
No hay nada que ahorrar.
❌ Cuando el hijo no está memoizado
useCallback ahí es placebo.
❌ Cuando el componente es pequeño
Un memo innecesario solo añade complejidad.
📌 Mi checklist personal (para evitar recaer)
Antes de usar useMemo o useCallback, pregúntate:
¿Esto realmente es costoso?
¿Estoy evitando recrear algo que sí afecta a un hijo memoizado?
¿Tengo forma de medirlo?
¿Si lo quito, pasa algo?
¿Estoy optimizando para un caso real o para sentirme "más pro"?
Si la respuesta honesta es NO…
ciérralo.
No memorices.
🏁 Lección aprendida
Después de entender esto, dejé de pelearme con memoization y empecé a verla como lo que es:
una herramienta quirúrgica, no una cinta adhesiva para todo.
Hoy optimizo menos, pero optimizo mejor.
Y React me lo agradece.
En el próximo post voy a hablar del Profiler de React y cómo medir renders de verdad, sin adivinar.
Nos leemos 👋
Top comments (0)