Rendimiento de React en 2026: arquitectura antes que useMemo
Deje que el Compilador de React se encargue de la memorización rutinaria, transfiera las tareas a los Componentes del Servidor y identifique los verdaderos cuellos de botella antes de utilizar useMemo y useCallback en cada archivo.
Durante mucho tiempo, los consejos sobre el rendimiento de React siguieron un ritual: al detectar una recálculación, envolverla con memo; al ver un cálculo, envolverlo con useMemo; al pasar una función, envolverla con useCallback. Si el componente parecía demasiado grande, dividirlo. Repetir. Ese enfoque funcionó con tanta frecuencia que se convirtió en un hábito automático.
El punto de equilibrio de React ha cambiado. Las API no se volvieron repentinamente inútiles. Lo que sí cambió es que la optimización está pasando de ser algo que cada componente gestiona manualmente a algo que los frameworks y compiladores pueden aplicar automáticamente. Los equipos que desarrollan aplicaciones con React y Next.js en 2026 deben actualizar su modelo mental en consecuencia.
La antigua mentalidad de optimización en React
Un patrón de componente común se veía así:
const filteredUsers = useMemo(
() => users.filter((user) => user.isActive),
[users]
);
const handleSelect = useCallback(
(id: string) => {
selectUser(id);
},
[selectUser]
);return (
<UserList
users={filteredUsers}
onSelect={handleSelect}
/>
);
La intención era clara: en la siguiente renderización, omitir nuevamente el filtrado de usuarios, evitar recrear la función de callback y preservar los hijos memorizados. La consecuencia oculta es la carga cognitiva. Ahora los desarrolladores deben lidiar con:
dependencies
references
closures
memoization
stale values
component boundaries
Una de las formas más baratas de introducir errores es “optimizar” tareas que nunca fueron problemáticas.
Llega el Compilador de React
El compilador propone un enfoque diferente. En lugar de indicar constantemente a React que recuerde un valor, se escribe código de componente normal y se deja que la compilación decida dónde resulta útil la memorización:
function ActiveUsersList({ users }) {
const filteredUsers = users.filter(
(user) => user.isActive
);
return (
<ul>
{filteredUsers.map((user) => (
<li key={user.id}>
{user.name}
</li>
))}
</ul>
);
}
Filtros legibles, sin memorización manual y sin arrays de dependencias que deban mantenerse actualizados. El compilador analiza el componente e inserta las optimizaciones adecuadas. Se trata de un cambio filosófico, no meramente estético.
Pero no elimines todos los useMemo
Una reacción excesiva común es eliminar todos los useMemo, useCallback y memo desde el primer día. Eso es demasiado drástico. Los puntos de llamada existentes pueden incluir un almacenamiento en caché intencional; la cobertura del compilador depende de la versión de React, la configuración y la estructura del código. Una opción más adecuada como valor por defecto es: no optimice manualmente primero; mida primero. Deje que el compilador se encargue de los casos seguros. Realice un análisis de rendimiento antes de añadir hooks personalizados. Mantenga la memorización explícita solo donde sea intencional y esté comprobada. El objetivo es reducir la complejidad innecesaria, no disminuir el número de hooks por sí mismo.
El rendimiento está ganando importancia
Evitar la recálculación de los componentes hijos es solo una parte del costo en React moderno. Una ruta de solicitud típica en Next.js se ve así:
Browser
↓
React
↓
Next.js
↓
Server Components
↓
Data fetching
↓
Database
↓
External APIs
Una página que tarda tres segundos en cargarse puede no tener nada que ver con la reconciliación de React. Lo que predomina son las consultas lentas, las APIs conversadoras, los paquetes grandes, las solicitudes secuenciales, las imágenes pesadas, los componentes del cliente innecesarios, el caché deficiente o el trabajo costoso en el servidor. Otro useMemo no solucionará esos problemas.
Los componentes del servidor cambian la ecuación
Los componentes del servidor, especialmente a través de Next.js, trasladan el trabajo fuera del navegador. La forma tradicional es:
Traditional approach
Server
↓
Large JavaScript bundle
↓
Browser
↓
Render everything
Un flujo más orientado al servidor:
Server
├── Fetch data
├── Render server components
└── Send necessary result
↓
Browser
↓
Interactive components
Tener menos JavaScript para descargar y ejecutar es una solución más efectiva que distribuir useCallback entre los componentes básicos.
La nueva pregunta: “¿Es necesario que esto esté en el lado del cliente?”
Esa pregunta es ahora una de las más importantes en la arquitectura de React. No es necesario que todo un panel de control sea un componente del cliente. Una división como esta sería adecuada:
Dashboard
├── Server
│ ├── Customer summary
│ ├── Revenue
│ ├── Recent jobs
│ └── Invoice totals
│
└── Client
├── Date picker
├── Filters
└── Interactive chart
mantiene la interactividad donde debe estar y deja los datos de resumen en el servidor. El rendimiento se convierte en una decisión relacionada con la propiedad, no solo en una cuestión de implementación.
Deje de optimizar lo que no ha medido
La intuición sigue llevando a las personas a:
users.map(...)
ir directamente a la conclusión de que “esto necesita memorización”. La consulta al mapa podría tardar menos de un milisegundo, mientras que cinco llamadas secuenciales a la API agotan el tiempo disponible. Mida primero con React DevTools Profiler, los paneles de rendimiento del navegador, Lighthouse, las herramientas de Next.js, Web Vitals y las métricas del servidor o la base de datos. Localice el cuello de botella y luego resuélvalo.
La nueva lista de verificación de rendimiento
Prefiera este orden en lugar de comenzar con:
useMemo
useCallback
React.memo
1. Reduzca el JavaScript
¿Este componente realmente necesita ejecutarse en el navegador?
2. Mejore la obtención de datos
Preste atención a:
waterfalls
duplicate requests
unnecessary requests
slow APIs
3. Almacene en caché de forma inteligente
Deje de volver a cargar datos que apenas cambian.
4. Optimice las consultas a la base de datos
React no puede compensar un plan de consulta deficiente.
5. Reduzca el tamaño del paquete
Cada dependencia innecesaria se convierte en carga adicional.
6. Optimice imágenes y recursos
Los medios de gran tamaño siguen dominando muchos tiempos de carga.
7. Mida el proceso de renderizado
Solo después de que aparezcan los costos reales de renderizado debería considerarse la memorización a nivel de componente.
¿Qué pasa con useMemo y useCallback?
Siguen siendo herramientas, no valores predeterminados. Reflejo antiguo: “Probablemente debería memorizar esto”. Mejor reflejo: “¿Tengo pruebas de que necesite memorización?”. Un costo real justifica:
const value = useMemo(
() => expensiveCalculation(data),
[data]
);
La concatenación de cadenas rara vez lo hace:
const fullName = useMemo(
() => `${firstName} ${lastName}`,
[firstName, lastName]
);
También es importante TypeScript
El tiempo de ejecución no es el único indicador del rendimiento. La velocidad de refactorización constituye la eficiencia del desarrollador. Los tipos fuertes hacen que los grandes conjuntos de código de React sean más seguros para modificar:
type Customer = {
id: string;
name: string;
email: string;
active: boolean;
};
Cuando cambia un componente o el contrato de una API, el verificador de tipos muestra inmediatamente los problemas detectados; esto es especialmente valioso cuando los asistentes de IA generan grandes diferencias que aún deben adaptarse al sistema.
La IA también está cambiando el desarrollo de React
En 2026 ya es normal pedir a un asistente que identifique la renderización innecesaria en el cliente, localice los segmentos de página lentos o realice refactorizaciones sin alterar el comportamiento. Las sugerencias no son mediciones reales. Sin análisis de rendimiento, se puede optimizar de forma excesiva un problema que en realidad nunca existió.
El verdadero futuro del rendimiento de React
El futuro no es “nunca usar useMemo”. Se trata de un ecosistema en el que los equipos invierten menos energía en microoptimizaciones menores de renderizado y más en la arquitectura. La jerarquía de prioridades es la siguiente:
1. Architecture
↓
2. Server vs Client
↓
3. Data fetching
↓
4. Caching
↓
5. Bundle size
↓
6. Rendering
↓
7. Micro-optimizations
Fíjese dónde se encuentra useMemo: cerca de la parte inferior, donde debe estar.
La regla a seguir en 2026
Escriba primero componentes simples de React. Deje que el compilador haga lo que pueda. Mida el rendimiento real. Luego optimice el verdadero cuello de botella. Evite componentes que se parezcan a:
useMemo(...)
useCallback(...)
memo(...)
useEffect(...)
useMemo(...)
useCallback(...)
solo porque “React necesita optimización”. El React moderno premia una buena arquitectura sobre código ingenioso. La mejor victoria a menudo no es reducir dos milisegundos en el renderizado, sino darse cuenta de que el componente nunca necesitó ejecutarse en el navegador en absoluto.
Lecturas relacionadas
- Haz menos trabajo primero: un listado de verificación de rendimiento en React antes de la memorización — Reduce los costos de la aplicación React evitando tareas innecesarias: usa debounce en las búsquedas, implementa paginación, gestiona el estado de forma adecuada, utiliza claves estables, traslada el procesamiento al lado del servidor y carga contenido de forma perezosa; luego aplica memorización solo si es necesario.
- Estado legendario para actualizaciones detalladas en React y React Native — Transfiere el estado activo a los observables de Estado Legendario para que las filas de la lista de reproducción y los temporizadores vuelvan a renderizar solo las celdas que han cambiado, en lugar de todo el subárbol de React Native.