El martes pasado, Mira, que lleva la mitad frontend de nuestro panel de administración en Inertia, me mandó una grabación de pantalla. Abre la vista previa de exportación de facturas, que tarda lo suyo en montarse porque pinta unas once mil filas de tabla. Luego escribe el nombre de un cliente en el buscador de la barra lateral, y los resultados se quedan ahí, congelados, hasta que termina la vista previa de la exportación. "¿Qué le importa al buscador la exportación?", escribió. Buena pregunta. En el lado de PHP dejamos de hacérnosla hace mucho, porque el propio runtime nos la respondió.

Piensa en lo que hace de verdad un pool de PHP-FPM. Un worker se queda atascado en una consulta de informe de 9 segundos, y la siguiente petición va a otro worker, hace su trabajo y vuelve en 40 ms sin enterarse siquiera de que el informe existe. El shared-nothing es una costumbre en la que ya ni reparamos. Cada petición nace y muere sola, así que una lenta no puede hacer que otra que no tiene nada que ver parezca lenta. Por lo que veo en los cambios de React 19.3, el lado del cliente está adoptando esa misma costumbre para las transiciones, y creo que es la decisión correcta. Además, convierte el frontend en un sitio más natural para pensar si vienes de PHP.

Vamos a los hechos. Una transición es lo que envuelves en startTransition(), y le dice a React que la actualización es real pero que puede ceder el paso a cualquier cosa urgente, como una pulsación de tecla. Antes de 19.3, si había dos transiciones en marcha a la vez, React podía atarlas entre sí, de modo que la barata acababa esperando a que terminara la cara. En 19.3, las transiciones que no tienen nada que ver entre sí pueden renderizarse de forma independiente. El buscador de Mira y su vista previa de exportación pasan a ser dos workers de FPM en lugar de un solo worker con una cola larga detrás. El artículo que me puso sobre la pista tiene el cuidado de añadir que cuánto ganas depende de lo que renderizas y de si las actualizaciones se tocan de verdad entre sí, y yo lo subrayaría.

Aquí hay una objeción de peso y quiero tomármela en serio. Nada de esto hace que algo vaya más rápido. Un componente que necesita 400 ms para renderizarse sigue necesitando 400 ms. Lo único que cambia React es cuándo se gasta ese tiempo y qué puede colarse delante. Un escéptico diría que una planificación más lista es una forma excelente de esconder un componente inflado, igual que un pool de FPM grande te deja ignorar una consulta horrorosa hasta que la base de datos se cae a final de mes. Yo he vivido ese final de mes. El pool mantuvo la web respondiendo, y también evitó que nadie arreglara la consulta durante dos años.

Así que sí, el aislamiento puede convertirse en una excusa. Aun así, me quedo del lado de darle la bienvenida, porque la alternativa es peor. Cuando todo está acoplado, el usuario paga tu código más lento en cada interacción, incluidas las que ni lo rozan. Con aislamiento solo paga por lo que de verdad ha pedido. Es un comportamiento por defecto mejor, y no te impide perfilar. Si acaso, hace que el perfilado sea más honesto, porque cuando la vista previa de la exportación ya no arrastra al buscador consigo, sus 400 ms aparecen en el profiler como un coste propio en lugar de esconderse dentro de los números de todos los demás.

Lo que yo sacaría de esto como desarrollador backend tiene menos que ver con las APIs de React y más con la forma de nuestras respuestas. La vista previa de exportación y el buscador de Mira llaman a endpoints de Laravel. Si esos dos endpoints comparten un bloqueo de sesión, o si en cada visita de Inertia se reconstruye un único payload de props gigantesco, el cliente puede planificar todo lo bien que quiera y esas dos tareas seguirán atadas en el servidor. La independencia tiene que existir de arriba abajo para que el planificador pueda sacarle partido. Ya sabemos cómo darle a cada pieza de la UI su propio endpoint ligero, con recargas parciales, rutas separadas y sin escrituras de sesión en las llamadas de solo lectura. Ahora hay una recompensa concreta por hacerlo.

Para ser justos, las transiciones nunca fueron para todo. Un input controlado sigue teniendo que actualizarse al instante, y el patrón de siempre sigue valiendo: deja como urgente el valor que escribes y mete en startTransition() solo el estado derivado que sale caro. Eso no ha cambiado. Lo nuevo es que ahora puedes tener varias de esas actualizaciones en segundo plano en marcha sin que te vuelvan como un único bloque, combinado y lento.

Donde de verdad tengo dudas es en la dinámica de equipo. En nuestra casa, quien escribe el endpoint casi nunca es quien envuelve la actualización en startTransition(), y el aislamiento en un lado solo compensa si el otro lado colabora. Así que te lo pregunto a ti, que sacas backends en PHP para frontends en React: cuando la UI empieza a dar tirones, ¿quién se encarga del arreglo en tu equipo, y algún cambio como el de 19.3 ha movido alguna vez esa frontera?