Inicio / Artículos / Rendimiento de React más allá del memo manual: estructura y programación

Rendimiento de React más allá del memo manual: estructura y programación

Consejo de la época de los compiladores: gestiona el estado, separa el trabajo urgente, envía menos JavaScript y luego memoriza los puntos críticos medidos.

803 palabras

Durante años, el consejo sobre el rendimiento de React consistía por defecto en envolver todo con las APIs memo:

const value = useMemo(() => expensiveCalculation(data), [data]);
const handleClick = useCallback(() => {
  doSomething(id);
}, [id]);export default React.memo(Component);
function ProductList({ products, onSelect }) {
  const processed = useMemo(
    () => processProducts(products),
    [products]
  );
  const handleSelect = useCallback(
    (id) => onSelect(id),
    [onSelect]
  );  return (
    <List
      products={processed}
      onSelect={handleSelect}
    />
  );
}
App
 │
 ├── Header
 ├── Sidebar
 ├── Search
 ├── ProductList
 └── Footer
function App() {
  const [query, setQuery] = useState("");
  // large component tree
}
App
 │
 ├── Header
 ├── Sidebar
 ├── Search
 │    └── query state
 ├── ProductList
 └── Footer
const [query, setQuery] = useState("");
const [isPending, startTransition] = useTransition();
function handleChange(event) {
  const value = event.target.value;  setQuery(value);  startTransition(() => {
    setSearchResults(filterProducts(value));
  });
}
User input
    │
    ├── urgent ───────► keep UI responsive
    │
    └── non-urgent ───► transition
const AnalyticsDashboard = lazy(
  () => import("./AnalyticsDashboard")
);
Initial JavaScript
       │
       ▼
┌─────────────────────┐
│ Everything          │
│ Dashboard           │
│ Analytics           │
│ Editor              │
│ Admin               │
└─────────────────────┘
Initial load
    │
    ├── Core UI
    │
    └── Later
          ├── Analytics
          ├── Editor
          └── Admin
"This component renders often."
        │
        ▼
Add useMemo
"This component renders often."
        │
        ▼
Why?
        │
 ┌──────┼───────────┐
 ▼      ▼           ▼
State  Expensive   Large
flow   work        subtree
 │      │           │
 ▼      ▼           ▼
Colocate  Optimize  Restructure
1. Measure
      ↓
2. Find the expensive work
      ↓
3. Fix component architecture
      ↓
4. Reduce unnecessary JavaScript
      ↓
5. Prioritize updates correctly
      ↓
6. Let React Compiler handle memoization
      ↓
7. Manually optimize only when evidence says you should

La memorización por sí sola no soluciona los problemas de lentitud en las aplicaciones. Un árbol perfectamente memorizado aún puede tener mal rendimiento debido a un estado excesivo, actualizaciones urgentes que realizan tareas no urgentes, o un JavaScript pesado en el hilo principal.

El compilador de React cambia la norma por defecto

El compilador automatiza muchos espacios de memorización. Esto dirige el esfuerzo humano hacia la estructura y la planificación, en lugar de colocar manualmente useMemo en todas partes.

Primero: coloca el estado cerca de donde se utiliza

Un estado de alto nivel en el árbol vuelve a renderizar los subárboles extensos. Coloca el estado junto con las hojas que lo necesitan; úsalo solo cuando sea necesario compartirlo.

Segundo: no hagas que las actualizaciones urgentes realicen trabajo no urgente

Mantén la capacidad de escritura y las animaciones responsivas. Pospone el trabajo no urgente mediante transiciones o valores diferidos para que las pulsaciones de teclado no se vean bloqueadas por filtros costosos.

Tercero: examina el JavaScript que estás enviando

Los bucles de sincronización grandes, los formateadores costosos y las listas ilimitadas dominan antes de que lo haga el reconciliador de React. Analiza el JavaScript, no solo lo que resaltan las herramientas de desarrollo de React.

Entonces, ¿cuándo deberías usar useMemo?

Sigue siendo útil para mantener la estabilidad referencial entre hijos que dejan de recibir props, y para cálculos puros realmente costosos, después de medir su impacto. No como solución por defecto para todos los valores.

La nueva mentalidad de rendimiento en React

Estructura → programación → enviar menos JavaScript → luego memorizar en microescala los puntos críticos. La memorización asistida por el compilador es una ayuda, no un sustituto del diseño.

Añada un presupuesto de rendimiento a las propuestas de cambio: tiempo necesario para la siguiente actualización visual del formulario principal, y una captura del perfilador de React para la ruta conocida por su alto consumo de recursos.

Las listas deben virtualizarse antes de memorizar cada fila. La memorización en una lista con 10,000 filas sigue siendo ineficaz.

Añada un presupuesto de rendimiento a las propuestas de cambio: tiempo necesario para la siguiente actualización visual del formulario principal, y una captura del perfilador de React para la ruta conocida por su alto consumo de recursos.

Las listas deben virtualizarse antes de memorizar cada fila. La memorización en una lista con 10,000 filas sigue siendo ineficaz.

Añada un presupuesto de rendimiento a las propuestas de cambio: tiempo necesario para la siguiente actualización visual del formulario principal, y una captura del perfilador de React para la ruta conocida por su alto consumo de recursos.

Las listas deben virtualizarse antes de memorizar cada fila. La memorización en una lista con 10,000 filas sigue siendo ineficaz.

Añadir un presupuesto de rendimiento a las PR: tiempo necesario para la siguiente actualización visual del formulario principal, y una captura del perfilador de React para la ruta conocida por su alto consumo de recursos.

Las listas deben virtualizarse antes de memorizar cada fila. Incluso al usar la función memo en una lista con 10,000 filas, se sigue perdiendo rendimiento.

Añadir un presupuesto de rendimiento a las PR: tiempo necesario para la siguiente actualización visual del formulario principal, y una captura del perfilador de React para la ruta conocida por su alto consumo de recursos.

Las listas deben virtualizarse antes de memorizar cada fila. Incluso al usar la función memo en una lista con 10,000 filas, se sigue perdiendo rendimiento.

Añadir un presupuesto de rendimiento a las PR: tiempo necesario para la siguiente actualización visual del formulario principal, y una captura del perfilador de React para la ruta conocida por su alto consumo de recursos.

Las listas deben virtualizarse antes de memorizar cada fila. Incluso al usar la función memo en una lista con 10,000 filas, se sigue perdiendo rendimiento.

Lecturas relacionadas