SolidJS: ¿Por qué tanto Suspense?

Spanish audio is available in the player settings
Rate this content
Bookmark

Solid captó la atención de la comunidad frontend al popularizar la programación reactiva con su convincente uso de Señales para renderizar sin re-renderizaciones. Los hemos visto adoptados en el último año en todo, desde Preact hasta Angular. Las Señales ofrecen un conjunto poderoso de primitivas que aseguran que tu interfaz de usuario esté sincronizada con tu estado, independientemente de los componentes. Un lenguaje universal para la interfaz de usuario frontend.


Pero, ¿qué pasa con lo Asíncrono? ¿Cómo logramos orquestar la carga y mutación de datos, el renderizado en el servidor y la transmisión? Ryan Carniato, creador de SolidJS, echa un vistazo a una primitiva diferente. Una que a menudo se malinterpreta pero que es igual de poderosa en su uso. Únete a él mientras muestra de qué se trata todo este Suspense.

Ryan Carniato
Ryan Carniato
28 min
01 Jun, 2023

Video Summary and Transcription

Suspense es un mecanismo para orquestar cambios de estado asíncronos en frameworks de JavaScript. Asegura la consistencia asíncrona en las interfaces de usuario y ayuda a evitar la erosión de la confianza y las inconsistencias. Los límites de Suspense se utilizan para elevar la obtención de datos y crear zonas de consistencia basadas en la interfaz de usuario. Pueden manejar los estados de carga de múltiples recursos y controlar la carga de estado en las aplicaciones. Suspense se puede utilizar para transiciones, proporcionando una experiencia de usuario más fluida y permitiendo la priorización de contenido importante.

Available in English

1. Introducción a Suspense en Frameworks de JavaScript

Short description:

Suspense es un mecanismo para orquestar cambios de estado asíncronos en los frameworks de JavaScript. Es un área complicada que ha requerido años de investigación para desarrollar los mejores patrones. Los frameworks de JavaScript dependen de garantías de ejecución síncrona para mantener las interfaces de usuario sincronizadas, pero lo asíncrono presenta desafíos. La reactividad es la forma en que los frameworks mantienen la vista sincronizada con los datos, con el objetivo de evitar la erosión de la confianza y las inconsistencias. Un ejemplo de un artículo introductorio explica la importancia de evitar suscripciones manuales que pueden llevar a interfaces de usuario desincronizadas. La historia del error de Facebook Messenger destaca la molestia y el impacto de una interfaz de usuario inconsistente, opacando el lanzamiento de la aplicación.

Está hablando sobre suspense. Suspense es un mecanismo para orquestar cambios de estado asíncronos en los frameworks de JavaScript. Lo encuentras en React, Vue y Solid, como mencioné. Y esta es un área complicada. Una que ha requerido años de investigación para desarrollar los mejores patrones. La razón es que los frameworks de JavaScript están diseñados para mantener las interfaces de usuario sincronizadas. Y dependen de garantías basadas en la ejecución síncrona. Lo asíncrono complica las cosas.

¿Cómo aseguramos que la interfaz de usuario sea consistente en estas condiciones? Bueno, primero debes entender a qué me refiero con asíncrono. Perdón, consistencia. Este ejemplo se extrae de un artículo introductorio que explica el funcionamiento interno de su biblioteca React. La reactividad es básicamente cómo los frameworks mantienen la vista sincronizada con tus datos. Cualquier sistema basado en suscripciones manuales está condenado a desincronizarse, como se muestra aquí. Esto es lo que todos los frameworks quieren evitar.

Imagina lo que sucede cuando ves esto. Erosiona la confianza. Puede que no creas lo que estás viendo y te veas obligado a recargar la página. Y puede persistir de formas aún más molestas que algo que se puede solucionar con una recarga. En una charla temprana de React, recuerdo replantear el desarrollo de aplicaciones web en Facebook. Jing Chen contó la historia de cómo Facebook Messenger tenía este error que seguía volviendo. Lo solucionaron. A veces, de manera laboriosa debido a lo complicada que era la lógica de sincronización. Y en ese momento, Messenger todavía era parte de la aplicación. El error era que las personas recibían notificaciones fantasma que indicaban que tenían un mensaje. Y ya habían visto o borrado todos sus mensajes. Una molestia aparentemente simple. Pero como usuario, pensarías que tienes un nuevo mensaje y no lo tienes. Al ocurrir esto varias veces al día, de repente comenzarías a ignorarlo y te perderías mensajes reales o algunos de los usuarios más obsesivos estarían llenos de quizás decepción y ansiedad, haciendo clic constantemente y sin ver nada. Este error aparentemente inofensivo era tan molesto para los usuarios que cada vez que Facebook lo lanzaba quedaba opacado por la demanda de solucionarlo.

2. Garantías de consistencia en modelos reactivos

Short description:

Los frameworks tienen garantías de consistencia en modelos reactivos, lo que nos permite confiar en esas garantías. Sin embargo, no todos los frameworks son iguales y cada uno tiene una idea diferente de la consistencia. La respuesta a cuál modelo es más correcto no es simple.

Arreglarían este error. No poder depender del software que utilizas puede ser paralizante. Afortunadamente, en los modelos reactivos que encuentras en los frameworks de UI, tenemos garantías de consistencia. Esto nos permite no enfocarnos en esos detalles y simplemente confiar en esas garantías.

Sin embargo, no todos los frameworks son iguales. Pero si entiendes las reglas, puedes depender de ellas. Este ejemplo fue realmente divertido para mí. Básicamente, tomé un estado, tomé un estado derivado, como el contador y el contador doble, y puse ese estado en el DOM y tomé una referencia a ese estado en el DOM. Y después, en un controlador de clics, hice clic y mostré en la consola los tres valores. Resulta que cada framework tenía una idea diferente de cómo se veía eso. Y honestamente, se podría argumentar que cada uno de estos modelos de consistencia es correcto. Así que podrían debatir entre ustedes cuál es más correcto. La respuesta no es tan simple.

3. Manejo de inconsistencia asíncrona con Suspense

Short description:

El desgarro es un ejemplo común de inconsistencia asíncrona. Ocurre cuando cambias de pestaña y la interfaz de usuario no se actualiza de inmediato. En React, esto puede suceder al obtener datos basados en el estado actual de la pestaña. Para evitar esto, puedes usar marcadores de posición, quedarte en el pasado o mostrar la función con actualizaciones optimistas. Estos problemas se resuelven utilizando suspense en los frameworks modernos.

Pero, ¿cómo se ve esto cuando hablamos de inconsistencia? El ejemplo más común que se me ocurre es algo llamado desgarro. Alguna vez he estado en un sitio de listado de películas, donde tienes nuevos lanzamientos y luego tal vez tienes tus favoritos en dos pestañas diferentes. Y tienes todas las vistas de pósteres. Lo que sucede cuando tienes desgarro puede ser que estés en los nuevos lanzamientos, puedes ver la pestaña de nuevos lanzamientos resaltada y puedes ver esos pósteres, y luego haces clic en tu pestaña de favoritos, y por un momento, ahora el título dice favoritos, la pestaña dice favoritos, pero sigues viendo los nuevos lanzamientos. Este es un ejemplo de inconsistencia asíncrona. Y honestamente, es bastante fácil que ocurra. Creo que todos hemos escrito código así. Este es un código de React solo como ejemplo, pero tienes, digamos, algún estado, como una categoría, y luego obtienes las películas basadas en ese estado. Sin embargo, es un problema un poco complicado, porque necesitas cambiar el estado a la nueva pestaña para que la aplicación sepa que debe obtener la nueva lista de películas, pero aún no tienes los datos para mostrarlos. Si construyes tu aplicación de manera sencilla, solo tienes una variable de estado para indicar en qué pestaña te encuentras. Y se usa tanto para activar la obtención de datos como para actualizar la interfaz de usuario. Esto naturalmente causa un estado inconsistente. Entonces, ¿cómo podemos evitar esto? Bueno, generalmente tenemos tres opciones. Podemos mostrar un marcador de posición para que simplemente no lo mostremos. Podemos quedarnos en el pasado. Pero esto es un poco complicado porque, como puedes imaginar, aún necesitas actualizar esa pestaña. Necesitas iniciar la obtención de datos mientras aún muestras el estado anterior. Y la otra opción es mostrar la función, pero mostrar la función también es limitado si aún no tienes los datos. En algunos casos, como las mutaciones, puedes usar lo que envías al servidor para informar esto. Y eso lo llamamos actualizaciones optimistas. Curiosamente, todos estos problemas se resuelven utilizando suspense en algunos frameworks modernos. Hoy me voy a enfocar solo en las primeras dos opciones por cuestiones de tiempo, pero créeme, aún hay mucho que abordar aquí.

4. Comprendiendo el Rol de Suspense

Short description:

Suspense es un mecanismo para crear límites en la representación de tu vista para garantizar la consistencia asíncrona para los usuarios de tu aplicación. No es una solución mágica para obtener cascadas de datos, sino más bien una forma de elevar la obtención de datos y leerlo donde se utiliza. Este enfoque permite establecer zonas de consistencia basadas en la interfaz de usuario y hace que el sistema sea resistente al cambio. Las señales, junto con las promesas y los límites de suspense, desempeñan un papel clave en este concepto.

Entonces, todo esto para resaltar, para que podamos hablar de esto, cuando te presentaron por primera vez el tema del suspense, probablemente alguien te dijo que era una forma de mostrar spinners de carga. Y no están equivocados, pero esto subestima la importancia de lo que está sucediendo aquí.

Suspense es un mecanismo para crear límites en la representación de tu vista para garantizar la consistencia asíncrona para los usuarios de tu aplicación. Esa es la definición que estoy utilizando. Esto se manifiesta de muchas formas, como esos spinners de carga, pero esa es solo una forma en la que podemos aprovecharlo.

Pero antes de seguir adelante, hay muchas cosas que el suspense no es. No es una especie de magia para curar las cascadas de obtención de datos en el código. Las cosas construidas en torno al suspense pueden informarse sobre la naturaleza asíncrona de las dependencias en tu aplicación, pero no pueden hacer lo imposible posible. La única forma de evitar las cascadas es obtener los datos más arriba en el árbol. Ya sea usando un compilador como Relay o cargadores explícitos, como los que encuentras en un kit de RemixSvelte, esto es imprescindible. En algunos casos, puedes eliminar las solicitudes duplicadas utilizando algún tipo de clave para ahorrar tiempo, pero la obtención de datos aún debe ocurrir más arriba de manera no bloqueante, y sinceramente, a veces estas cascadas no se pueden evitar de todos modos.

El punto en común en todas las implementaciones de suspense es que el mecanismo se basa en la lectura de valores asíncronos futuros. No se basa en la obtención de datos. Esta es una distinción muy importante porque nos permite elevar la obtención de datos por encima y luego leerlo donde lo usamos. Esto nos permite establecer zonas de consistencia basadas en la interfaz de usuario. Hace que el sistema sea resistente al cambio a medida que construyes tus diseños y a medida que se agregan más funcionalidades asíncronas, tienes la misma experiencia de carga. Puedes abordar los límites de suspense como un diseñador más que como un desarrollador.

Es importante entender la importancia de la lectura. Necesitas un mecanismo que incluso puede ser un primitivo de datos para registrar estas lecturas. Todos podemos usar promesas, pero las promesas se ejecutan una vez. Necesitas algo más que una fábrica de promesas, algo que genere múltiples promesas y que se puedan almacenar en caché. Afortunadamente, en Solid, ya tenemos algo que funciona así. Como puedes imaginar, es mi respuesta para casi todas las preguntas. Señales. Las señales ya son multivaluadas e interceptan las lecturas. En nuestro caso, tenemos una señal asíncrona especial, que estoy mostrando en la pantalla. Las promesas, junto con los límites de suspense, son la pieza fundamental detrás de todo lo que mostraré hoy. Hagamos un poco de codificación en vivo para mostrar de qué estoy hablando. Eso es mucha teoría pesada. Pasemos a esto.

5. Cargando Spinners y Límites de Suspense

Short description:

Esta parte introduce el concepto de los spinners de carga y una aplicación básica con pestañas. La aplicación utiliza un mini enrutador para mostrar la pestaña seleccionada. El presentador explica cómo mejoraron la aplicación para utilizar una API de recursos y obtener datos de usuario. Demuestran el uso de señales y la obtención de datos de John Lennon. Para manejar la obtención asíncrona de datos, envuelven el enrutador en un límite de suspense con una alternativa. El resultado es un mecanismo de captura que muestra la carga al actualizar o navegar entre pestañas.

Donde esto comienza, sí, comienza con los spinners de carga. Así que voy a entrar aquí un segundo. Ahí vamos. Construí esta aplicación muy básica. Tiene algunas pestañas que van y vienen. Nada demasiado especial aquí.

Tenemos una lista desordenada que muestra qué pestaña está seleccionada, y Solid tiene estos flujos de control. Esto es como un mini enrutador, donde mostramos una pestaña en función de cuál es actualmente la pestaña seleccionada, que es solo una señal con detalles. Esto es muy similar a nuestro ejemplo de categoría de películas que mencioné hace un momento.

Pero lo que voy a hacer aquí es actualizar este hola mundo para usar realmente nuestra API de recursos, que va a utilizar nuestro ID de usuario como entrada para obtener el usuario, que es una API falsa que robé de una demostración de React que hicieron hace unos cuatro años, donde tienen algunos datos sobre los Beatles. Así que sí, gracias al equipo de React por hacer grandes ejemplos de demostración que puedo robar. De todos modos, volvamos allí.

En lugar de hola mundo, lo único que vamos a hacer es que las señales son una función, así que simplemente vamos a llamarla como una función y hacer esto, .name, y de repente ahora estamos cargando nuestros datos de John Lennon en ella. Y si te fijas cuando voy y vengo, está en blanco por un segundo. No es genial, pero al menos estamos cargando algunos datos asíncronos. ¿Qué hacemos aquí? Bueno, envolvamos nuestro enrutador en un límite de suspense. Muy bien. Suspense. Y lo que podemos hacer aquí es establecer un fallback. Y nuestro fallback, simplemente voy a hacer un div con class equals loader. Así es, class. No class. Name. Y simplemente pondremos algo como loading aquí. De acuerdo. Ahora, cuando actualizo la página, oh, tengo un error tipográfico, ¿verdad? ¿Dónde está mi error tipográfico? Cierra el suspense. Gracias. De acuerdo, cuando actualizo la página, vemos loading por un momento. Y cuando vamos y venimos, vemos loading de nuevo. Así que muy simplemente, tenemos este tipo de captura.

6. Manejo de Múltiples Recursos con Suspense

Short description:

Al utilizar otro límite de suspense, podemos manejar los estados de carga de múltiples recursos en paralelo. Esto garantiza una experiencia de usuario consistente al navegar hacia adelante y hacia atrás. La carga inicial se retrasa durante un tiempo específico para simular diferentes duraciones de carga. La solución a esto es utilizar otro límite de suspense.

Y lo que quiero decir con captura de todo es si vuelvo a esta página de detalles y agrego otro recurso. Resulta que, gracias a la API falsa de React. También tengo una lista de publicaciones. Así que puedo agregar otro recurso. Y como ambos dependen del ID de usuario, podemos obtenerlos en paralelo. Obtener publicaciones. Y hagamos un poco más. Agreguemos un fragmento que cerré. Afortunadamente. Y luego confiamos en Prettier para arreglar esto por mí en un segundo. Pero vamos a hacer una lista desordenada nuevamente. Y vamos a hacer... ¿Qué es? Solids. Para el componente. Que necesito importar. Y... Cada publicación... Vamos a publicar... Es... Sí, disculpen por todo el tecleo. ¿Post dot text? Sí. De acuerdo. Ahora, si todo funciona, ahora tenemos algunos detalles. Lo que has notado aquí es que tenemos la misma experiencia donde ese mismo marcador de posición maneja ambos estados de carga. Y al ir y venir, lo vemos de nuevo. Lo único... Esto está tardando un poco más, porque retrasé la carga inicial 600 milisegundos y retrasé el otro un segundo y medio. Entonces lo que podemos hacer aquí es, bueno, podemos usar otro límite de suspense. Podemos ir... De acuerdo.

7. Utilizando Límites de Suspense para Controlar la Carga del Estado

Short description:

Vamos a envolver esto en un límite de suspense para controlar cómo se carga el estado en tu aplicación. El suspense funciona con cualquier promesa y puede resolver cualquier cosa. También se puede utilizar fuera del navegador para determinar cuándo el servidor ha terminado de renderizar y qué partes de la página están listas. El concepto de suspense fue introducido en el Marco Framework y ahora se utiliza en Solid.

Bien, vamos a envolver esto también en un límite de suspense. Y la forma en que funciona el suspense es que busca el límite de suspense más cercano a donde ocurre la lectura, que en realidad ocurre aquí cuando estamos leyendo la publicación. La otra lectura ocurre cuando estamos leyendo el usuario. Así que simplemente podemos anidar nuestro límite de suspense y hacer otro fallback aquí. Y de nuevo... ¿Qué es? Class igual a loader. Y digamos que esta vez está cargando publicaciones. Y si hice eso correctamente, formateemos nuestro documento.

Tengo que importar suspense. Ahora puedes ver que lo hemos dividido. Y muestra cada pieza a medida que avanzamos. De manera similar, podemos obtener este tipo de cascada o secuencia de estados de carga. Pero lo interesante de esto es que, si esto, digamos, se carga más rápido, como 200 milisegundos, simplemente se saltará el segundo estado de carga porque no tiene que esperar más tiempo. Así que esta es una herramienta realmente poderosa para poder controlar de manera genérica según el diseño cómo se carga el estado en tu aplicación.

Es fácil mostrar esto con la obtención de datos, pero realmente funciona con cualquier promesa. Técnicamente no necesita ser una promesa, en teoría, pero las promesas tienen algunas propiedades agradables. Primero, están diseñadas para resolverse o rechazarse. Puedes asumir que la API está construida con ellas y esperar una resolución. En segundo lugar, solo se completan una vez. Esto puede ser menos conveniente en un mundo de flujos de datos asíncronos, pero para nuestros propósitos tenemos un contrato. Tenemos esta especie de garantía. Puedes usar esto para resolver cualquier cosa. Dispositivos asíncronos, solo los alimentas y luego los límites de suspense lo manejan por ti. Pero tampoco hay una regla que diga que el suspense solo debe ejecutarse en el navegador. Esta conciencia de lo asíncrono no solo nos dice cuándo hemos terminado de renderizar en el servidor, sino qué partes de la página están listas a medida que están listas.

Aunque el suspense se le atribuye a React, un concepto muy similar fue introducido en Marco Framework en 2013, y eso es lo que impulsa eBay.com. Sé un poco sobre esto porque me uní al equipo de Marco hace unos años antes de trabajar en Netlify y me quedé asombrado y pensé, vale, tengo que añadir esto a Solid. Así que básicamente, de la misma manera en que cargamos datos en el cliente, podemos enviar partes de la página desde el servidor. Resulta que puedes dejar la respuesta abierta al servir una página web y simplemente seguir agregando HTML en la parte inferior.

8. HTML, Script Tags, and Streaming

Short description:

Y ese HTML puede contener etiquetas de script, mover el HTML a su posición, serializar datos y activar la hidratación. La demo funciona de manera similar a Solid. La obtención de datos ocurre en el servidor, pero se ve similar a lo que hicimos antes. Podemos controlar cuándo comenzamos a transmitir usando defer stream true. Los marcadores de carga pueden ser bruscos. Mantener las cosas en el pasado es más complicado. Navegar a la siguiente página en un carrusel puede llevar a estados inconsistentes.

Y ese HTML, bueno, puede contener etiquetas de script. Y esas etiquetas de script pueden mover el HTML a su posición y serializar cualquier data y activar la hidratación. Así que todo este trabajo puede ocurrir independientemente de que el framework realmente se haya cargado en la página.

Tomé esta demostración de la página de inicio de Marco, pero funciona de manera muy similar a cómo lo hacemos en Solid. Y para hacer eso, tengo otro ejemplo de código. Pero no realmente otro. Lo que hice en realidad fue usar el metaframework Solid Start, pero esencialmente ahora tenemos HTML en la cabeza y algunas otras cosas, pero lo que verás es casi la misma demostración nuevamente donde tengo un límite de suspense con carga, envolviendo nuestro enrutador, y luego tengo un componente de encabezado y pie de página para demostrar que no estoy inventando esto . Y si voy a nuestras rutas y obtengo nuestra ruta de índice, lo que verás es que el componente se ve muy similar al que acabamos de crear donde tenemos nuestros dos recursos obteniendo las cosas, y un límite de suspense anidado para mostrar exactamente las mismas cosas. Y la razón por la que quiero mostrar esto es que cuando recargas la página, se ve realmente similar a lo que acabamos de hacer. La única diferencia aquí es que ahora la obtención de data ocurre en el servidor. Es exactamente el mismo código, pero funciona directamente en SSR. Y lo interesante aquí, y voy a mostrar esto muy rápido, con suerte, es que obtenemos nuestro HTML de vuelta, ya sabes, tenemos nuestra cabeza y algo de CSS que se carga aquí, pero lo que es realmente interesante aquí es que el cuerpo principal tiene el encabezado y el pie de página, como mostré, y luego realmente ves la carga aquí, y algunos comentarios de marcador de posición y cosas, algunos scripts para comenzar, pero luego cerramos el cuerpo y el HTML, por lo que el documento está listo, pero luego, ¿qué es esto al final? Una plantilla donde tenemos a John Lennon y la carga de publicaciones, por lo que tenemos el siguiente estado de la interfaz de usuario, los data que necesitamos para hidratarlo, que es solo este John Lennon, y esto en realidad es el código aquí, que simplemente mueve las cosas desde la parte inferior del documento e inserta, y luego debajo de eso, bueno, a medida que se completa, obtenemos otra plantilla, y esta tiene nuestro listado de publicaciones, y nuevamente, los data que necesitamos para hidratarlo, por lo que simplemente se va incrementando en la página. Ahora esto es obviamente bastante genial, pero tal vez no quieras mostrar la página hasta que el título aparezca, y hay una manera bastante fácil de hacerlo. Podemos simplemente, para nuestro recurso, agregar defer stream true, y ahora, cuando recargo la página, puedes ver que espera hasta que John Lennon esté allí antes, por lo que tenemos un control completo sobre cuándo comenzamos a transmitir. Podemos, ya sabes, hacer nuestra autenticación primero, asegurarnos de que la persona esté bien, y luego transmitir parte del contenido que puede tardar más en cargarse, pero si te fijas de nuevo, es todo el mismo código que hemos estado usando en el otro ejemplo, ya sea que estés usando SSR, no necesitas componentes del servidor ni ningún tipo de cosas sofisticadas. Esto es solo suspense más recursos. De acuerdo. Los marcadores de carga son útiles, pero a veces pueden ser bruscos, sacando al usuario de la experiencia. Cuando la página se carga inicialmente, no tenemos nada que mostrar, por lo que mostrar un marcador de carga es, ya sabes, una gran indicación, pero en las navegaciones posteriores, ya tenemos contenido para mostrar, la página actual. Entonces, ya mencioné que mantener las cosas en el pasado es un poco más complicado de hacer. No podemos simplemente bloquear una función asíncrona, no podemos simplemente hacer un componente asíncrono y esperar que funcione. Eso se debe a que algún cambio de estado no relacionado o acción del usuario final podría interactuar con la página y podría ver ese estado inconsistente cuando lo esté leyendo. Y no obtendrás el resultado esperado. Un ejemplo perfecto es, supongamos que navegas al siguiente. Tienes un carrusel y navegas a la siguiente página.

¿Dos minutos? ¿De verdad? Oh. De acuerdo, genial. Así que hay una cuenta regresiva de ocho minutos aquí. De acuerdo.

9. Mostrando Transición con Use Transition

Short description:

Eliminé el ejemplo de suspense anidado y agregué un use transition para envolver el set tab. Esto asegura que cada cosa asíncrona que provenga de esto esté en su propia transacción. Cuando cambiamos a la otra página, no muestra el estado de carga hasta que todos los datos estén cargados. Mantiene todo el conjunto.

Bueno, al menos quiero mostrar una transición aquí. Básicamente, eliminé el ejemplo de suspense anidado, por lo que puedes ver que tienes esta alternativa. Y lo que podemos hacer aquí es agregar un use transition. Y const start, o lo siento, al revés. Is pending start equals use transition. Y lo que esto hace básicamente es que vamos a tomar la transición de inicio y vamos a envolver nuestro set tab con ella. Y lo que esto hace es más o menos decir, hey, esto, y cada cosa asíncrona que provenga de esto, debería estar en su propia especie de transacción. Y solo hacer eso por sí solo hará que cuando cambiemos a la otra página, no sea muy interactivo, pero verás que en realidad no mostró el estado de carga. En realidad se mantuvo. Si realmente miras la pestaña, no cambia la pestaña hasta que todos los data se carguen. En realidad mantiene todo el conjunto.

10. Using Suspense for Transitions

Short description:

And of course that's a little bit jarring. So what we can actually do is we can use that is pending here. I'm just going to use solid's class list finding here and then go pending, class is pending. And if I do that, see initial load has loading. But then it grays it out, gives you kind of an indicator. In many cases this kind of interaction is a little bit more gentle on the user than just swapping across. The last thing I want to show is transitions are kind of global. They have to freeze everything. They freeze that tab even though the tab isn't under the suspense boundary. Sometimes you want to opt in and opt out of it. The way we can do that is by essentially bringing back that nested suspense boundary I had a moment ago. The reason is any existing suspense boundary will hold in the transition, but any new suspense boundary will go to the fallback. For this reason, we can then go div class equals loader, and we'll just put loading posts. What you're going to see now is initial loading has a cascade, but when we go back to the initial page, it's going to wait for the John and then only do the delay then. You can prioritise important content that you want to hold the page to, and load the slower content or less important content later. So this is a very quick whirlwind tour through Suspense. I would have told you it works a bit like a Git merge and a rebase. That's the mechanics of it, but it's not that important. Ultimately, Suspensive Transitions provide useful tools for making our user interfaces consistent, and you can use the same API to solve a whole bunch of problems. That's a big benefit both to the end-users and the developer. It isn't just about performance, it isn't just about data fetching, it's about making easier to create UIs that users can trust and that behave in expected ways, and offer smooth experience no matter how they navigate your web application.

And of course that's a little bit jarring. So what we can actually do is we can use that is pending here. I'm just going to use solid's class list finding here and then go pending, class is pending. And if I do that, see initial load has loading. But then it grays it out, gives you kind of an indicator. In many cases this kind of interaction is a little bit more gentle on the user than just swapping across.

The last thing I want to show is transitions are kind of global. They have to freeze everything. They freeze that tab even though the tab isn't under the suspense boundary. Sometimes you want to opt in and opt out of it. The way we can do that is by essentially bringing back that nested suspense boundary I had a moment ago. The reason is any existing suspense boundary will hold in the transition, but any new suspense boundary will go to the fallback. For this reason, we can then go div class equals loader, and we'll just put loading posts. What you're going to see now is initial loading has a cascade, but when we go back to the initial page, it's going to wait for the John and then only do the delay then. You can prioritise important content that you want to hold the page to, and load the slower content or less important content later.

So this is a very quick whirlwind tour through Suspense. I would have told you it works a bit like a Git merge and a rebase. That's the mechanics of it, but it's not that important. Ultimately, Suspensive Transitions provide useful tools for making our user interfaces consistent, and you can use the same API to solve a whole bunch of problems. That's a big benefit both to the end-users and the developer. It isn't just about performance, it isn't just about data fetching, it's about making easier to create UIs that users can trust and that behave in expected ways, and offer smooth experience no matter how they navigate your web application. Anyway, like what you heard today, find more information on SolidJS.com, follow me on Twitter, or if you like nerding out on JS Framework stuff, I stream every Friday for five hours on Twitch and YouTube when I'm not going to these conferences.

QnA

Señales y React

Short description:

Las señales son populares en los frameworks de JavaScript, excepto en React. El enfoque hacia la resolución de problemas más allá de los límites de los componentes está impulsando la necesidad de un manejo de estado que pueda manejar el estado global y local. Esto permite nuevas posibilidades como la hidratación parcial y la capacidad de reanudación. Mientras que React se centra en el modelo de componentes, las señales proporcionan una forma de ir más allá de los componentes y definir límites basados en las propias señales.

Muchas gracias. Ryan, por favor acércate a la pared de interrogación, párate allí para que los francotiradores puedan apuntar bien. Muchas preguntas, solo cuatro minutos y 49 segundos. Así que la pregunta con mayor puntuación. Me he dado cuenta de que las señales están presentes en la mayoría de los frameworks de JavaScript, excepto en React. ¿Por qué son tan populares y extendidas y por qué React las odia? Sí, esa es una excelente pregunta. Honestamente, creo que estamos llegando a un punto en el que los problemas que estamos tratando de resolver van más allá de los límites de los componentes. Creo que tener, siempre hemos necesitado un manejo de estado y poder tener el mismo manejo de estado para el estado global, para el estado local y alejarnos del modelo de componentes va a permitir mucho del futuro de la web. Hidratación parcial, capacidad de reanudación, muchas de las nuevas palabras de moda que estás escuchando. No solo es genial para el rendimiento, sino que también abre nuevas categorías completas de cómo podemos hacer más con menos JavaScript. ¿Por qué React no está tan interesado? Es casi como en el extremo opuesto fundamental. Dijeron que podrían usar señales en el fondo, pero están muy enfocados en su modelo de componentes. Ven a sus componentes como reactivos, lo cual es una idea genial, pero como dije estoy muy interesado en lo que va más allá de los componentes y la única forma de hacerlo es que los límites sean las propias señales. Gracias, amigo.

Usando Datos en Caché y Suspense en Solid JS

Short description:

Sí, el almacenamiento en caché es definitivamente posible con el gancho de hidratación y envoltorios como React Query. El fallback de suspense en Solid activa un nuevo montaje solo si hay un cambio en la lógica reactiva. UseTransition está implementado en Solid y React, pero no en Vue. Los atributos de datos HK en Solid ayudan a garantizar el orden correcto de los elementos DOM durante la hidratación. Incluir primitivas reactivas en la especificación de JavaScript sería una tarea monumental, dada la falta de acuerdo entre los frameworks.

¿Hay alguna forma de usar datos en caché y, de ser así, cómo se activa una nueva búsqueda? Sí, nuestros recursos tienen un gancho de hidratación que puedes usar para preceder a tu caché cuando la página se carga por primera vez, pero desde allí, dentro de ese buscador de data, puedes leer sincrónicamente desde una caché o ir a modo asíncrono, por lo que hay muchos envoltorios, es posible que hayas oído hablar de React Query, tenemos una consulta que simplemente envuelve el recurso e implementa una caché encima y desde allí tienes acceso a toda la serialización automática, transmisión y todo eso, solo con las bibliotecas de terceros así que sí, el almacenamiento en caché es definitivamente posible.

Entendido. ¿El fallback de suspense activa un nuevo montaje de los componentes secundarios o se guardan sus estados guardados? Sí, lo hace. Sí, depende. No necesariamente activa un nuevo montaje porque en Solid simplemente lo sacamos. Si hay una lógica condicional debajo, como una declaración de mostrar, sí se volverá a montar porque habrás cambiado la cosa, pero si solo lo sacas de la vista y lo vuelves a poner, no se considera nada si no ha cambiado nada reactivamente entonces no se ejecutará nada reactivamente. Nuestro montaje es simplemente un efecto, es solo en función del cambio de señal, si eso tiene sentido.

¿UseTransition es específico de Solid JS y hay una alternativa o alternativas en otros frameworks? UseTransition es en realidad una API de React que copié, pero creo que solo Solid y React lo han implementado realmente. Creo que hay algunos frameworks más pequeños, pero de los frameworks conocidos, no creo que Vue lo haga. Es muy poderoso, pero necesitas el renderizado concurrente, necesitas esa forma de dividir las cosas. En el caso de React, simplemente renderizan un VDom diferente y fusionan las diferencias. En el caso de Solid, es como un montón de nodos que obtenemos y reorganizamos. Así que, creo que solo Solid y React.

Esta también es una pregunta que me hacía. ¿Cuáles eran esos extraños e interesantes atributos de datos HK? Sí, verás esto en cualquier aplicación SSR en Solid. Cuando hacemos hidrataciones parciales como componentes del servidor, hay menos de ellos. Pero en general, JSX se ejecuta fuera de orden. Literalmente puedes crearlo en cualquier lugar. Y por esa razón no puedo confiar en el orden del DOM. Por lo tanto, la secuencia en la que se crea el contenido se codifica de nuevo en el DOM para que cuando hidratemos, podamos extraer las secciones del código de la vista, por así decirlo. En nuestro caso, todos estos eran elementos separados, así es como se codificaron. Pero si tienes grandes bloques de elementos estáticos, solo tendrás un atributo HK de datos por parte de la plantilla porque clonamos grandes secciones continuas de la plantilla.

Genial. ¿Y crees que las primitivas reactivas como señales y refs deberían ser incluidas en la especificación de Ecumascript de JavaScript en algún momento? Tal vez. Quiero decir, eso permitiría muchas cosas, pero ahora mismo no podemos... Viste esa diapositiva donde mostré cuatro frameworks con cuatro resultados diferentes. Ni siquiera hemos acordado cómo funciona eso. Entrar en la especificación sería una tarea monumental, creo.

Genial. Gracias. Hans Romans y compatriotas, aplaudan a Ryan Cardiano. En realidad, necesito conseguir otro.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

Building Better Websites with Remix
React Summit Remote Edition 2021React Summit Remote Edition 2021
33 min
Building Better Websites with Remix
Top Content
Remix is a new web framework from the creators of React Router that helps you build better, faster websites through a solid understanding of web fundamentals. Remix takes care of the heavy lifting like server rendering, code splitting, prefetching, and navigation and leaves you with the fun part: building something awesome!
React Compiler - Understanding Idiomatic React (React Forget)
React Advanced Conference 2023React Advanced Conference 2023
33 min
React Compiler - Understanding Idiomatic React (React Forget)
Top Content
React provides a contract to developers- uphold certain rules, and React can efficiently and correctly update the UI. In this talk we'll explore these rules in depth, understanding the reasoning behind them and how they unlock new directions such as automatic memoization. 
Speeding Up Your React App With Less JavaScript
React Summit 2023React Summit 2023
32 min
Speeding Up Your React App With Less JavaScript
Top Content
Too much JavaScript is getting you down? New frameworks promising no JavaScript look interesting, but you have an existing React application to maintain. What if Qwik React is your answer for faster applications startup and better user experience? Qwik React allows you to easily turn your React application into a collection of islands, which can be SSRed and delayed hydrated, and in some instances, hydration skipped altogether. And all of this in an incremental way without a rewrite.
Full Stack Documentation
JSNation 2022JSNation 2022
28 min
Full Stack Documentation
Top Content
Interactive web-based tutorials have become a staple of front end frameworks, and it's easy to see why — developers love being able to try out new tools without the hassle of installing packages or cloning repos.But in the age of full stack meta-frameworks like Next, Remix and SvelteKit, these tutorials only go so far. In this talk, we'll look at how we on the Svelte team are using cutting edge web technology to rethink how we teach each other the tools of our trade.
From GraphQL Zero to GraphQL Hero with RedwoodJS
GraphQL Galaxy 2021GraphQL Galaxy 2021
32 min
From GraphQL Zero to GraphQL Hero with RedwoodJS
Top Content
We all love GraphQL, but it can be daunting to get a server up and running and keep your code organized, maintainable, and testable over the long term. No more! Come watch as I go from an empty directory to a fully fledged GraphQL API in minutes flat. Plus, see how easy it is to use and create directives to clean up your code even more. You're gonna love GraphQL even more once you make things Redwood Easy!
Jotai Atoms Are Just Functions
React Day Berlin 2022React Day Berlin 2022
22 min
Jotai Atoms Are Just Functions
Top Content
Jotai is a state management library. We have been developing it primarily for React, but it's conceptually not tied to React. It this talk, we will see how Jotai atoms work and learn about the mental model we should have. Atoms are framework-agnostic abstraction to represent states, and they are basically just functions. Understanding the atom abstraction will help designing and implementing states in your applications with Jotai

Workshops on related topic

Building WebApps That Light Up the Internet with QwikCity
JSNation 2023JSNation 2023
170 min
Building WebApps That Light Up the Internet with QwikCity
Featured WorkshopFree
Miško Hevery
Miško Hevery
Building instant-on web applications at scale have been elusive. Real-world sites need tracking, analytics, and complex user interfaces and interactions. We always start with the best intentions but end up with a less-than-ideal site.
QwikCity is a new meta-framework that allows you to build large-scale applications with constant startup-up performance. We will look at how to build a QwikCity application and what makes it unique. The workshop will show you how to set up a QwikCitp project. How routing works with layout. The demo application will fetch data and present it to the user in an editable form. And finally, how one can use authentication. All of the basic parts for any large-scale applications.
Along the way, we will also look at what makes Qwik unique, and how resumability enables constant startup performance no matter the application complexity.
Back to the Roots With Remix
React Summit 2023React Summit 2023
106 min
Back to the Roots With Remix
Featured Workshop
Alex Korzhikov
Pavlik Kiselev
2 authors
The modern web would be different without rich client-side applications supported by powerful frameworks: React, Angular, Vue, Lit, and many others. These frameworks rely on client-side JavaScript, which is their core. However, there are other approaches to rendering. One of them (quite old, by the way) is server-side rendering entirely without JavaScript. Let's find out if this is a good idea and how Remix can help us with it?
Prerequisites- Good understanding of JavaScript or TypeScript- It would help to have experience with React, Redux, Node.js and writing FrontEnd and BackEnd applications- Preinstall Node.js, npm- We prefer to use VSCode, but also cloud IDEs such as codesandbox (other IDEs are also ok)
Learn Fastify One Plugin at a Time
Node Congress 2021Node Congress 2021
128 min
Learn Fastify One Plugin at a Time
Workshop
Matteo Collina
Matteo Collina
Fastify is an HTTP framework for Node.js that focuses on providing a good developer experience without compromising on performance metrics. What makes Fastify special are not its technical details, but its community which is wide open for contributions of any kind. Part of the secret sauce is Fastify plugin architecture that enabled developers to write more than a hundred plugins.This hands-on workshop is structured around a series of exercises that covers from basics "hello world", to how to structure a project, perform database access and authentication.

https://github.com/nearform/the-fastify-workshop
Build a Universal Reactive Data Library with Starbeam
JSNation 2023JSNation 2023
66 min
Build a Universal Reactive Data Library with Starbeam
WorkshopFree
Yehuda Katz
Yehuda Katz
This session will focus on Starbeam's universal building blocks. We'll use Starbeam to build a data library that works in multiple frameworks.We'll write a library that caches and updates data, and supports relationships, sorting and filtering.Rather than fetching data directly, it will work with asynchronously fetched data, including data fetched after initial render. Data fetched and updated through web sockets will also work well.All of these features will be reactive, of course.Imagine you filter your data by its title, and then you update the title of a record to match the filter: any output relying on the filtered data will update to reflect the updated filter.In 90 minutes, you'll build an awesome reactive data library and learn a powerful new tool for building reactive systems. The best part: the library works in any framework, even though you don't think about (or depend on) any framework when you built it.
Table of contents- Storing a Fetched Record in a Cell- Storing multiple records in a reactive Map- Reactive iteration is normal iteration- Reactive filtering is normal filtering- Fetching more records and updating the Map- Reactive sorting is normal sorting (is this getting a bit repetitive?)- Modelling cache invalidation as data- Bonus: reactive relationships
Build a Product Page with Shopify’s Hydrogen Framework
React Advanced Conference 2022React Advanced Conference 2022
81 min
Build a Product Page with Shopify’s Hydrogen Framework
WorkshopFree
David Witt
David Witt
Get hands on with Hydrogen, a React-based framework for building headless storefronts. Hydrogen is built for Shopify commerce with all the features you need for a production-ready storefront. It provides a quick start, build-fast environment so you can focus on the fun stuff - building unique commerce experiences. In this workshop we’ll scaffold a new storefront and rapidly build a product page. We’ll cover how to get started, file-based routing, fetching data from the Storefront API, Hydrogen’s built-in components and how to apply styling with Tailwind.You will know:- Get started with the hello-world template on StackBlitz- File-based routing to create a /products/example route- Dynamic routing /products/:handle- Hit the Storefront API with GraphQL- Move the query into the Hydrogen app- Update the query to fetch a product by handle- Display title, price, image & description.- Tailwind styling- Variant picker and buy now button- Bonus if there’s time: Collections page
Prerequisites: - A Chromium-based browser (StackBlitz)- Ideally experience with React. A general web development background would be fine.