Volver a React Básico

Rendimiento en React

React re-renderiza componentes cuando el estado o las props cambian. Las siguientes herramientas permiten omitir re-renderizados innecesarios.

React.memo

Memoriza el resultado del renderizado de un componente:

import { memo } from 'react'; interface Props { nombre: string; onClick: () => void; } // Solo re-renderiza si `nombre` u `onClick` cambian const TarjetaUsuario = memo(function TarjetaUsuario({ nombre, onClick }: Props) { console.log("Renderizando TarjetaUsuario"); return <div onClick={onClick}>{nombre}</div>; });

useCallback

Memoriza una función para mantener la misma referencia entre renderizados:

import { useState, useCallback, memo } from 'react'; const Boton = memo(({ onClick, label }: { onClick: () => void; label: string }) => { console.log("Botón renderizado:", label); return <button onClick={onClick}>{label}</button>; }); function Contador() { const [cuenta, setCuenta] = useState(0); const [otro, setOtro] = useState(0); // Sin useCallback: nueva función en cada renderizado → Botón siempre re-renderiza // Con useCallback: misma función referencia → Botón NO re-renderiza cuando `otro` cambia const incrementar = useCallback(() => setCuenta(c => c + 1), []); return ( <> <Boton onClick={incrementar} label={`Cuenta: ${cuenta}`} /> <button onClick={() => setOtro(n => n + 1)}>Otro: {otro}</button> </> ); }

useMemo

Memoriza el resultado de un cálculo costoso:

import { useState, useMemo } from 'react'; function ListaFiltrada({ items }: { items: string[] }) { const [filtro, setFiltro] = useState(''); // Solo recalcula cuando `items` o `filtro` cambian const filtrados = useMemo(() => { console.log("Filtrando..."); return items.filter(item => item.toLowerCase().includes(filtro.toLowerCase())); }, [items, filtro]); return ( <> <input value={filtro} onChange={e => setFiltro(e.target.value)} placeholder="Filtrar..." /> <ul>{filtrados.map(item => <li key={item}>{item}</li>)}</ul> </> ); }

Carga Diferida con lazy y Suspense

import { lazy, Suspense } from 'react'; // El componente solo se carga cuando se necesita const Tablero = lazy(() => import('./pages/Tablero')); const Configuracion = lazy(() => import('./pages/Configuracion')); function App() { return ( <Suspense fallback={<div className="spinner">Cargando...</div>}> <Routes> <Route path="/tablero" element={<Tablero />} /> <Route path="/config" element={<Configuracion />} /> </Routes> </Suspense> ); }

Guía de Rendimiento

HerramientaCuándo usar
React.memoUn componente hijo re-renderiza con las mismas props
useCallbackPasas callbacks a componentes memorizados
useMemoCálculo costoso que depende de pocas dependencias
lazy()Rutas o modales grandes que no se necesitan de inmediato

Regla general: No optimices prematuramente. Primero perfila con las DevTools de React y luego aplica estas herramientas donde hay cuellos de botella reales.