Cómo utilizar Suspense y GraphQL con Apollo para construir excelentes experiencias de usuario

Rate this content
Bookmark

Para muchos desarrolladores de aplicaciones, GraphQL es fundamental para construir excelentes experiencias de usuario. Con la introducción de React Suspense, los desarrolladores tienen una forma ergonómica de orquestar estados de carga para mejorar el status quo. En esta charla, el equipo de Apollo Client te mostrará cómo construimos una aplicación no trivial utilizando las nuevas características de Suspense de Apollo Client, características de GraphQL como la directiva @defer, y cómo combinarlas para construir excelentes experiencias de usuario en tus propias aplicaciones.

29 min
20 Oct, 2023

Video Summary and Transcription

Esta charla discute el uso de suspense y GraphQL con el cliente Apollo para construir excelentes experiencias de usuario. Explica los conceptos básicos de React Suspense y cómo obtener datos en suspense con los nuevos hooks de suspense del cliente Apollo. La charla también cubre la optimización de la experiencia de carga añadiendo límites de suspense, utilizando la directiva defer en GraphQL, e integrando hooks de suspense con las transiciones de React 18. Los planes futuros incluyen nuevas APIs como suspenseful use fragment y lazy use background query en Apollo Client 3.9. También se mencionan estrategias de prueba para suspense en componentes y la personalización de estados de carga.

Available in English

1. Introducción a la Charla

Short description:

Estamos emocionados de estar aquí en Londres para hablar sobre el uso de suspense y GraphQL con el cliente Apollo. También discutiremos sobre cómo construir excelentes experiencias para el usuario final. Permítanos presentarnos rápidamente. Soy Gerald Miller, un ingeniero de software principal en Apollo, y puedes encontrarme en línea como Gerald Miller. Soy Alessia Balissario, una ingeniera de software en Apollo, y estoy en AlessBell.

Qué día tan increíble. Estamos muy emocionados de estar aquí con todos ustedes en Londres. Y vamos a hablar sobre cómo usar suspense y GraphQL con el cliente Apollo y cómo construir experiencias realmente excelentes para el usuario final. Pero primero, permítanos presentarnos muy rápidamente porque Amber ya hizo un gran trabajo. No sé si se va a decir algo nuevo aquí, pero yo soy Gerald Miller. Soy un ingeniero de software principal en Apollo trabajando como mantenedor en el cliente Apollo. Y puedes encontrarme prácticamente en todas partes en línea con mi nombre de usuario Gerald Miller. Y yo soy Alessia Balissario. Soy una ingeniera de software también en Apollo y estoy en AlessBell.

2. Introducción a React Suspense y Apollo Client

Short description:

Esta charla trata sobre la reintroducción de los conceptos básicos de React Suspense en el contexto de las aplicaciones web renderizadas por el cliente y se centra en cómo obtener datos en suspense con los nuevos hooks de suspense de Apollo Client. No cubriremos los componentes del servidor React ni el SSR en streaming. Consulta el paquete experimental de Next.js para obtener más información.

Así que vamos a sumergirnos y hablar sobre lo que vamos a cubrir hoy. Esta charla va a ser sobre la introducción o reintroducción para algunos de ustedes, de algunos conceptos básicos de React Suspense en el contexto de las aplicaciones web renderizadas por el cliente y centrándonos en cómo obtener datos en suspense con los nuevos hooks de suspense de Apollo Client que lanzamos en agosto en la versión 3.8 de Apollo Client. Y también hablar sobre lo que no vamos a cubrir hoy. No vamos a cubrir los componentes del servidor React o el SSR en streaming. Parece que hay muchas sesiones aquí hoy. Esperamos que eches un vistazo a algunos de esos avances súper interesantes en el ecosistema de React. Pero si tienes curiosidad sobre este espacio con Apollo específicamente, puedes consultar nuestro paquete experimental de Next.js como ves en la pantalla aquí. También un saludo a nuestro co-mantenedor Lens que ha hecho gran parte del trabajo para esto aquí. Así que si tienes preguntas sobre esto, definitivamente contáctalo. También lo que no vamos a cubrir es cómo implementar realmente el soporte para suspense en una biblioteca de obtención de datos, porque en realidad es un poco más complicado de lo que parece.

3. Explorando React Suspense y Estados de Carga

Short description:

Volvamos a 2018 cuando Andrew Clark destacó la diferencia en los estados de carga entre plataformas nativas como iOS y la web. React suspense va más allá de la representación de los estados de carga y proporciona una forma componible de gestionar las transiciones. Discutiremos el suspense en el contexto de Apollo Client y el hook UseSuspenseQuery. Presta atención a los cuadros de colores en la pantalla, que representan áreas de nuestra interfaz de usuario con hooks UseQuery. Echemos un vistazo a la UX de carga.

Bueno, volvamos en el tiempo a 2018 cuando Andrew Clark, miembro del equipo central de React, envió este tweet en enero de 2018. Esto fue más de un mes antes de la charla de Dan Abramov en JSConf Islandia titulada más allá de React 16, que dio una mirada al futuro de React e introdujo suspense con algunas de las primeras demostraciones públicas. Creo que este es un buen lugar para empezar porque Andrew aquí está hablando de ciertos patrones de interacción que simplemente se sentían mucho más agradables y aún lo hacen de muchas maneras en plataformas nativas como iOS en comparación con la web y las experiencias que se ven más a menudo en esas plataformas.

Andrew escribió, una razón por la que iOS se siente mejor que la web, menos estados de carga innecesarios. Mira lo que sucede aquí en esta grabación de pantalla cuando tocas una opción en la aplicación de configuración. En lugar de hacer una transición inmediata y mostrar un spinner por una fracción de segundo, se pausa por un momento hasta que la vista está lista y esa vista se desliza. Mucho más fluido. Creo que esto es realmente previsor, fue en 2018, y presagió mucho de hacia dónde iba el ecosistema en términos de gestión de estas transiciones en la web.

Sí. Entonces, si has usado Apollo durante algún tiempo, probablemente has usado este hook bastante veces, useQuery. Esta es la forma en que normalmente obtienes data en tus aplicaciones hoy en día. Esto viene con realmente dos exportaciones que usas la mayoría de las veces, la propiedad data y el booleano de carga que usas para determinar cuándo mostrar un estado de carga en tus componentes. Solo para echar un vistazo a un pequeño ejemplo aquí, tenemos este pequeño componente de álbumes aquí que usa el hook useQuery para obtener algunos data y mostrar este booleano de carga. No es sorpresa cuando tocas este botón, ves este estado de carga aquí. Cuando ese booleano de carga es verdadero, obtenemos ese pequeño bit. Cuando termina de cargar, podemos ver nuestra lista de álbumes aquí. Y así, mientras acabamos de mirar el status quo y ese destello de un spinner de carga, y vamos a hablar mucho sobre los estados de carga hoy, y cómo eso impacta en la UX de nuestras aplicaciones que estamos construyendo, realmente queríamos poner una advertencia ahí fuera de que React suspense no se trata solo de tener un mecanismo diferente para representar los estados de carga. Solo una API diferente para mostrar spinners y fallbacks. Realmente nos da esta forma muy componible, muy Reacty de orquestar y gestionar estas transiciones en nuestras aplicaciones. Así que va mucho más allá de los simples estados de carga, si quieres pensar en ello de esa manera.

Entonces, en términos de Apollo Client, estamos aquí para hablar de suspense, y estamos hablando de suspense en Apollo Client. Vamos a hablar de esto en el contexto de un hook que lanzamos en Apollo Client 3.8, llamado UseSuspenseQuery. ¿Qué es UseSuspenseQuery? Esencialmente es una versión suspenseful de nuestro hook UseQuery que obtiene algunos data que está integrado con todas las características de suspense de React 18, que incluye las transiciones de React 18. Así que durante la mayor parte del resto de la charla, en realidad vamos a estar mirando esto en el contexto del clon de Spotify que construimos aquí. Y hay un par de áreas en la pantalla a las que queremos que prestes atención mientras avanzamos a través de algunas de estas demostraciones aquí. ¿Ves todos estos cuadros de colores en la pantalla? Cada uno de estos representa un área de nuestra interfaz de usuario que tiene un hook UseQuery que está cargando algunos data del servidor. Esto es realmente para tener una idea de cómo funciona el status quo hoy, y cómo podemos hacer esto mejor con el hook UseSuspenseQuery y simplemente el suspense de React 18. Para tener una idea de cómo se ve la UX de carga hoy, vamos a echar un vistazo a esto aquí. Sí, así que aquí vemos cada uno de esos cuatro componentes cuando nuestra aplicación se carga por primera vez. De nuevo, están usando UseQuery bajo el capó, y podemos ver el efecto popcorn mientras la UI se carga.

4. Transición a UseSuspenseQuery

Short description:

Cada componente renderiza su propio fallback de carga y los datos tan pronto como la solicitud de red los devuelve. Estamos haciendo la transición de UseQuery a UseSuspenseQuery. Comenzamos con el componente del menú de usuario. Eliminamos el Booleano de carga y el estado de carga ya que Suspense se encarga de ello. El tipo de consulta se convierte en el tipo de consulta del menú de usuario en la aplicación habilitada para Suspense. Vemos una pantalla en blanco brevemente antes de que se cargue el UserMenu. Necesitaremos un SuspenseBoundary para un fallback de carga.

Cada componente es responsable de renderizar su propio fallback de carga, y va a renderizar data tan pronto como su solicitud de red devuelva esos data. No tenemos más control sobre ello que eso, simplemente estamos dejando que estos componentes se rendericen cuando los data estén listos.

Es un poco visualmente distractorio, tener esas cuatro áreas cargadas completamente dependiendo de cuándo se resuelve esa solicitud de red. Así que en realidad vamos a escribir algo de código juntos. Vamos a hacer la transición de esta aplicación habilitada para UseQuery a una aplicación habilitada para UseSuspenseQuery.

Así que vamos a abrir esta demostración aquí, y de nuevo, como dije, con esto es con lo que vamos a trabajar hoy. Sólo para refrescar, esta es exactamente la misma experiencia que viste en ese video hace un segundo. Ese efecto de palomitas de maíz que ves cuando se cargan los data. Y sólo para orientarnos un poco con esta aplicación aquí, aquí tengo mi diseño aquí. Puedes ver esas cajas de colores, cada uno de esos componentes allí, la barra lateral, el menú de usuario, la ruta, y la barra de reproducción, que cada uno representa una de esas áreas que carga algunos data.

Así que vamos a empezar y en realidad convertir uno de estos componentes a UseSuspenseQuery. Vamos a empezar con el menú de usuario allí, que es esa caja verde en la parte superior derecha. Así que para hacerlo, aquí está mi componente, UseQuery. Ves que tengo mi consulta GraphQL, mi importación de UseQuery, y un sitio bastante familiar aquí, ese data y los Booleanos de carga. Cuando ese Booleano de carga es verdadero, devolvemos nuestro estado de carga, y eso es lo que vemos.

Así que para convertir esto a Suspense, voy a empezar importando UseSuspenseQuery, reemplazar el uso aquí, y algo que vas a notar de inmediato cuando hagamos este cambio es que obtenemos este error aquí, la propiedad de carga no existe en el tipo UseSuspenseQueryResult. Y eso es porque con la mecánica de Suspense, en realidad no necesitamos ese Booleano de carga porque vamos a dejar que Suspense se encargue de esto por nosotros. Así que no tiene sentido, en realidad podemos eliminar eso. Y debido a eso, ya no necesitamos nuestro estado de carga. Algo a lo que también debes prestar atención aquí, con esto, si fuera a echar un vistazo al tipo de esa propiedad data, si estás acostumbrado a usar esto con UseQuery, estás acostumbrado a ver una unión con indefinido aquí también. Con la aplicación habilitada para Suspense, en realidad funciona como si esto fuera un código sincrónico. Ves que nuestro tipo de consulta aquí es ese tipo de consulta de UserMenu, lo cual es realmente genial, permite algunas cosas bonitas sobre esto. Para esta demostración, queremos hacer un cambio. Nos gusta dar pequeños pasos y ver qué hace ese cambio en nuestra aplicación. Así que volvamos a nuestra aplicación aquí y refresquémosla para ver qué hizo ese cambio.

Bueno, ahora estamos viendo una pantalla en blanco por una fracción de segundo, y en la primera pintura vemos que el UserMenu fue cargado allí. Fue bastante rápido, así que tal vez podamos refrescar de nuevo, Gerald. Así que no verás el resaltado verde alrededor del UserMenu en la parte superior derecha porque para el momento en que nuestra aplicación se renderiza por primera vez, los data están presentes para ese UserMenu. Así que estamos obteniendo los data para nuestro UserMenu con nuestro hook habilitado para Suspense, pero no estamos mostrando un fallback de carga todavía. Para eso, vamos a necesitar un SuspenseBoundary.

5. Añadiendo Suspense a los Componentes

Short description:

Vamos a añadir suspense a nuestros componentes uno por uno. Comenzamos con el componente UserMenu, envolviéndolo con el componente Suspense y utilizando el estado de carga de UserMenu como fallback. Después de refrescar, vemos el resaltado verde alrededor del UserMenu en su estado de carga. Ahora vamos a añadir límites de suspense y usar la consulta de suspense en los componentes de la barra lateral y de la barra de reproducción. Reemplazamos las importaciones con useSuspenseQuery, eliminamos el booleano de carga y el estado, y hacemos los cambios necesarios en el diseño.

Así que vamos a añadir eso, Gerald. Vamos a hacerlo. Así que voy a venir aquí a mi diseño, y para añadir suspense, voy a importar el componente Suspense de React. Y luego simplemente vamos a envolver esto, nuestro UserMenu, aquí con eso. Si puedo dar en la pantalla correcta, este es el problema de ser tan alto en esto aquí. Y esto va a tomar un solo prop, que es el componente que queremos mostrar cuando el componente está suspendido. Así que aquí, simplemente voy a usar ese estado de carga de UserMenu aquí. Y de nuevo, pasos de bebé. Vamos a refrescar y ver qué hizo este cambio aquí.

Genial. Así que ahora vemos el resaltado verde alrededor del UserMenu mientras está en su estado de carga. Pero por lo demás, todo lo demás no ha cambiado. Quiero decir, toda la UX sigue siendo totalmente inalterada, ¿verdad? Así que vamos a añadir límites de suspense y usar la consulta de suspense en nuestros otros tres componentes antes de que podamos hacer un poco más de progreso aquí. Genial. Así que simplemente voy a empezar. Vamos a la barra lateral aquí. Lo mismo que hicimos con el UserMenu. Voy a reemplazar mi importación con useSuspenseQuery. Ya no necesitamos ese booleano de carga, lo que significa que puedo deshacerme de ese estado de carga en mi componente. Haremos lo mismo con la barra de reproducción aquí. useSuspenseQuery. Vamos a reemplazar el uso, deshacerse del booleano de carga. Y espero que estén empezando a ver un poco de un patrón aquí. Una de las cosas que queríamos asegurarnos de hacer con la consulta de suspense es hacer que se sienta muy familiar a useQuery en que tiene muchas de las mismas opciones y tipo de sensación que tiene. Obviamente, la ergonomía de cómo manejas ese estado de carga es un poco diferente. Pero esperamos que en la mayoría de los casos, cambiar a suspense sea más o menos tan fácil como esto es. Así que vamos a conseguir nuestro último aquí. useSuspenseQuery. Deshacerse del booleano de carga. Y luego en nuestro diseño, vamos a añadir nuestros fallbacks de suspense alrededor de cada uno de estos.

6. Optimizando la Experiencia de Carga

Short description:

Voy a copiar esto varias veces. Y luego asegurémonos de que cada uno de estos use los estados de carga correctos aquí. Este es el play bar. Gracias a Dios por prettier, de lo contrario mi código se vería horrendo. Suspense no es una varita mágica que podemos agitar en nuestro código y mejorar la UX. Pero ahora que todos nuestros componentes están usando suspense para mostrar esas alternativas, tenemos un superpoder aquí porque podemos reorganizar estos límites de suspense. Hagamos el primer cambio real sustantivo aquí a la experiencia de carga envolviendo toda nuestra aplicación en un solo límite de suspense en lugar de esos cuatro límites granulares para cada componente. Así que tenemos una sola actualización en la pantalla ahora, solo por el hecho de poder mover ese límite de suspense al nivel más externo de nuestra aplicación. Pero ahora digamos que estamos empezando a interactuar con nuestro clon de Spotify aquí. Queremos escuchar una lista de reproducción diferente. Vemos algo interesante, que es que veo que esa alternativa de suspense aparece cuando navego a otra ruta aquí. Hemos ido un poco demasiado al extremo en una dirección de tener un solo límite de suspense para toda nuestra aplicación. Al hacer la transición de la ruta, esa transición y esas solicitudes de red para buscar una nueva lista de reproducción están activando esa única alternativa de suspense para toda nuestra aplicación. Obviamente, esa no es la experiencia de usuario que queremos aquí.

Voy a copiar esto varias veces. Y luego asegurémonos de que cada uno de estos use los estados de carga correctos aquí. Este es el play bar. Gracias a Dios por prettier, de lo contrario mi código se vería horrendo.

Bueno, de nuevo, pasos de bebé. Vamos a refrescar esto y ver qué pasa. Y es un poco anticlimático porque aún nada ha cambiado, ¿verdad? Suspense no es una varita mágica que podemos agitar en nuestro código y mejorar la UX. Todo lo que hemos hecho es cambiar el mecanismo que estamos usando para renderizar, para mostrar esa alternativa de carga, para ser suspense en lugar de que nuestros componentes sean responsables de renderizar esas alternativas de carga.

Pero ahora que todos nuestros componentes están usando suspense para mostrar esas alternativas, tenemos un superpoder aquí porque podemos reorganizar estos límites de suspense. Y entonces hagamos el primer cambio real sustantivo aquí a la experiencia de carga envolviendo toda nuestra aplicación en un solo límite de suspense en lugar de esos cuatro límites granulares para cada componente. Genial. Entonces, como antes, voy a agregar un límite de suspense aquí. Esta vez va a ser alrededor de toda mi aplicación. Asegurémonos de usar el estado de carga correcto aquí. Voy a eliminar todos esos límites de suspense que agregamos antes. Así que ahora aquí tenemos un solo límite de suspense alrededor de todo. Veamos qué hace este cambio a nuestra aplicación aquí. Ah, tada. Así que tenemos una sola actualización en la pantalla ahora, solo por el hecho de poder mover ese límite de suspense al nivel más externo de nuestra aplicación. Y debo decir, eso es mucho más agradable a la vista, tener una sola pintura en la pantalla con todos nuestros data listos para que el usuario interactúe con ellos.

Pero ahora digamos que estamos, ya sabes, empezando a interactuar con nuestro clon de Spotify aquí. Queremos escuchar una lista de reproducción diferente. Gerald, ¿por qué no vamos y navegamos por ahí y elegimos algo más para escuchar? Sí, eso está genial. Así que mi hija estaría emocionada si todos escucháramos su lista de reproducción juntos. Así que voy a navegar aquí y vemos algo interesante, que es que veo esa alternativa de suspense aparecer cuando navego a otra ruta aquí. Entonces, ¿qué podría estar pasando aquí, Alessia? Sí. Así que hemos ido un poco demasiado al extremo en una dirección de tener un solo límite de suspense para nuestra aplicación completa. Así que al hacer la transición de la ruta, ya sabes, esa transición y esas solicitudes de red para buscar una nueva lista de reproducción están activando esa única alternativa de suspense para toda nuestra aplicación. Y, ya sabes, obviamente esa no es la user experience que queremos aquí.

7. Añadiendo un Segundo Componente Suspense

Short description:

Añadimos un segundo componente suspense alrededor de nuestra ruta para mantener el diseño persistente mientras el componente de ruta interna se suspende. Cuando refrescamos y navegamos de nuevo a nuestra lista de reproducción avanzada de React, la carcasa exterior de nuestra aplicación se desactiva primero, seguida de un ligero retraso mientras se busca el componente de ruta. Si el límite de suspense interno está listo para renderizar antes que el límite de suspense externo, React coordina los tiempos. Usamos la directiva at synthetics en nuestras consultas para entender los tiempos. Al eliminar la directiva synthetics y refrescar la página, se muestran los efectos de una carga de ruta de lista de reproducción más rápida.

Queremos mantener ese Chrome de la aplicación, ese tipo de diseño persistente en la pantalla mientras nuestro usuario navega y el componente de ruta interna se suspende. Así que vamos a añadir un segundo componente suspense alrededor de nuestra ruta. Genial. Así que voy a entrar aquí alrededor de la ruta, que es ese componente que se suspende mientras navegamos alrededor. Asegurémonos de que estamos usando el componente correcto aquí, estado de carga de la ruta. Vamos a refrescar y luego vamos a navegar de nuevo a nuestra lista de reproducción avanzada de react aquí. Y ahora podemos ver que hemos vuelto a la user experience que estábamos buscando. Bien. Sí. Esto se ve genial. Y así vemos que, ya sabes, ahora cuando cargamos en nuestra la carcasa exterior de nuestra aplicación se desactiva primero, y luego hay otro ligero retraso mientras seguimos buscando el componente de ruta, que luego se desactiva con sus data cuando está listo para renderizar. Pero, Gerald, ¿qué pasa si el límite de suspense interno, ese componente de ruta tiene sus data y está listo para renderizar antes que ese límite de suspense externo? Sí, esa es una gran pregunta. Inviértelo. Sí. Sí. Así que para controlar estos tiempos que podemos ver, sólo voy a señalar que algo que notarán en nuestras consultas aquí, estamos usando esta directiva at synthetics aquí sólo para entender mejor cómo funcionan cada uno de estos tiempos. Así que de nuevo, queremos ver qué pasa si esa ruta de la lista de reproducción se carga mucho más rápido que nuestra carcasa exterior. Así que voy a eliminar esta directiva synthetics y vamos a refrescar y ver qué pasa aquí.

8. Optimizando la Experiencia de Carga con la Directiva Defer

Short description:

Si nuestro componente de ruta interna está listo para renderizar antes que la carcasa exterior, React puede coordinar eso para nosotros. En el peor de los casos, tendremos dos actualizaciones en la pantalla, pero en el mejor de los casos, tendremos una única actualización. Podemos mejorar la experiencia de carga utilizando la directiva defer en GraphQL. Esto nos permite cargar algunos datos más rápido y transmitir partes más lentas más tarde. Cuando nuestro componente de ruta es más lento, todavía vemos dos actualizaciones en la pantalla.

De acuerdo. Entonces, si nuestro componente de ruta interna está listo para renderizar antes que la carcasa exterior, ahora, gracias al uso de suspense, React puede coordinar eso para nosotros y orquestarlo. Así que nunca veremos el límite de suspense interno antes que el externo, pero eso significa que, ya sabes, ahora en el peor de los casos, si nuestra ruta interna está lista un poco más tarde que nuestra aplicación shell, tendremos dos actualizaciones en la pantalla. Pero por otro lado, en el mejor de los casos, cuando está listo, ya sabes, alrededor del mismo tiempo o antes, tendremos una única actualización muy agradable en la pantalla en el mejor de los casos escenario. Y todo eso es simplemente gracias al poder de suspense y al uso de estas herramientas que React nos da, lo cual es realmente agradable.

Así que ahora veamos si cargamos algunas pistas más aquí. Sí, en realidad, primero voy a ir a cada uno de estos componentes, porque probablemente viste directivas sintéticas alrededor de cada uno de esos, y queremos tener una mejor idea de cómo se verá la verdadera experiencia del usuario final aquí. Así que simplemente voy a ir a cada una de estas consultas. Voy a eliminar esto aquí. Vamos a la barra de reproducción. Lo mismo, simplemente deshazte de esta directiva sintética. Ya no la queremos. Y ahora vemos que el estado de carga es mucho más como cabría esperar. Sin embargo, hay algo que señalar aquí, y es que si refresco esto, esa lista de reproducción que vemos aquí en realidad todavía tarda un poco demasiado para nuestro gusto en cargar esto aquí. Y queremos mejorar esta experiencia. Ahora hemos hecho algunas cosas con suspense, pero también queremos hacer algunas cosas con GraphQL porque GraphQL también nos da algunas herramientas geniales aquí. No sé cuántos de ustedes han visto alguno de los avances de la especificación últimamente, pero hay una nueva directiva de etapa dos que está casi lista para el uso generalizado llamada defer que nos permite marcar parte de nuestra consulta como algo que puede ser transmitido en un momento posterior. Así que nos da la capacidad de decir, Oye, entendemos que puede haber una parte lenta de nuestra consulta aquí, pero queremos obtener algunos datos más rápido. Y luego cargaremos algunas de esas cosas lentas más tarde. Así que fingimos que hemos hecho algunas investigaciones y vemos que nuestro campo de pistas aquí es lo que realmente está tardando más en cargar aquí y lo que nos gustaría ver, estamos bien si esas pistas se cargan un poco más tarde, pero nos gustaría ver esos detalles de la lista de reproducción un poco más rápido aquí así que podemos usar defer. Voy a usar un fragmento en línea aquí y vamos a refrescar eso y ver qué qué nos da defer aquí. Bueno, agradable. Así que ahora vimos dos actualizaciones en la pantalla. Vimos que nuestro componente de ruta se renderizó al mismo tiempo que nuestra carcasa de aplicación y esas pistas diferidas se cargaron en esa segunda renderización en la pantalla, pero Gerald, ¿qué pasa ahora si nuestro componente de ruta es un poco más lento?

Sí, esa es una gran pregunta. Así que volvamos y agreguemos nuestra confiable directiva sintética aquí, si puedo escribir correctamente timeout. Añadamos un segundo de latencia a esto y refresquemos y veamos qué pasa aquí. Probemos eso de nuevo. Hay que amar el WiFi de la conferencia, ¿verdad? O tal vez ni siquiera lo guardé. Bueno, lo que todavía estamos viendo son dos actualizaciones en la pantalla. El WiFi de la conferencia, te lo digo.

9. Optimizando la Experiencia de Carga con Transiciones

Short description:

Agregar capas adicionales de límites de suspense y fallbacks de carga te brinda un control más granular sobre las transiciones de estado de UX de carga. Integramos los hooks de suspense con las transiciones de React 18 para mejorar la experiencia de carga. Al usar transiciones y eliminar directivas sintéticas, podemos evitar los fallbacks de suspense y mantener la interfaz de usuario existente en la pantalla. Hoy, aprendimos cómo migrar los hooks de obtención de datos para usar la consulta de suspense, optimizar la experiencia de carga moviendo los límites de suspense, usar defer para agregar fallbacks adicionales y marcar las solicitudes de red como transiciones en React.

Veamos aquí. Vale, todavía estamos viendo esas dos actualizaciones en la pantalla. Pero si nuestro tiempo de espera en el componente de ruta en nuestra consulta de lista de reproducción estaba funcionando, lo que íbamos a mostrar en este momento era el cambio en UX de ir a dos actualizaciones a la pantalla en el peor de los casos a tres actualizaciones en la pantalla en el peor de los casos puedes imaginar que nuestra carcasa de aplicación se carga primero, luego tendríamos el componente de ruta que se desbloquearía en una segunda renderización en la pantalla, y luego las pistas que están envueltas en defer serían esa tercera actualización en la pantalla. Así que la principal conclusión aquí es realmente solo esta idea de que agregar capas adicionales de suspense límites y fallbacks de carga te brinda un control más granular sobre estas transiciones de estado de UX de carga en general en tu aplicación. Pero hay un compromiso aquí. Podemos mostrar algo de contenido antes a los usuarios en el mejor de los casos, pero en el peor de los casos vamos a agregar momentos adicionales en nuestra aplicación donde estamos mostrando fallbacks de carga en el peor de los casos.

Así que una última cosa, mencionamos al principio que integramos los hooks de suspense con las transiciones de React 18. Vamos a echar un vistazo a eso aquí. Aquí tengo mi lista de reproducción. Voy a desplazarme hacia abajo porque quiero escuchar más pistas en la parte inferior. Vemos algo interesante aquí, que es que a medida que me desplazo y voy a cargar más pistas, vemos que se suspende de nuevo y obtengo un fallback de carga aquí. ¿Cómo podríamos buscar mejorar esto? Algo a destacar aquí es en mi lista de reproducción, para aquellos de ustedes que han usado Apollo durante cualquier cantidad de tiempo, han utilizado la API fetch more para cargar datos en una consulta paginada. En este caso estamos haciendo un escenario de desplazamiento infinito. Tenemos un fetch more exportado desde use suspense query que estamos llamando en esta función handle load more. Cuando llamamos a fetch more, está causando que nuestro componente se suspenda de nuevo porque estamos volviendo a ese estado de carga. Vamos a hacer esto un poco mejor trayendo una transición que nos permite ver lo que tenemos en pantalla y evitar ese fallback de suspense. Antes de hacerlo, también vamos a eliminar las directivas sintéticas ya que no queremos esperar dos segundos para cargar más pistas. Para agregar una transición, solo voy a importar la API start transition de React y vamos a envolver mi llamada fetch more en start transition. Esto le dirá a React que marque esto como una transición. Cuando este componente se suspenda, va a dejar lo que vemos en pantalla y evitar ver ese fallback. Vamos a refrescar. Nos desplazaremos hacia abajo aquí y ahora obtenemos la UX que esperábamos. Mucho mejor. Entonces, ¿qué aprendimos hoy? Miramos nuestro clon de Spotify comenzando con use query debajo del capó y luego migrando nuestros hooks de obtención de datos para usar nuestro nuevo hook habilitado para suspense use suspense query. Luego vimos cómo mover los límites de suspense en nuestra aplicación podría cambiar, impactar drásticamente la experiencia de carga. Y luego vimos cómo usar defer para agregar fallbacks adicionales y, ya sabes, despriorizar algunos de los campos en nuestra consulta. Luego vimos cómo marcar una de nuestras solicitudes de red provenientes de nuestra llamada fetch more aquí como una transición en React para decirle a React que mantenga la interfaz de usuario existente en la pantalla mientras hacemos esa solicitud de red en segundo plano. Así que esa es nuestra demostración para hoy. Sí, gracias. Gracias.

10. Conclusión y Planes Futuros

Short description:

No llegamos a hablar de toda la historia de suspense. Lanzamos otros dos hooks en Apollo client 3.8, use background query y use read query. En el futuro, estamos trabajando en Apollo client 3.9 con nuevas APIs como suspenseful use fragment y lazy use background query. El código de esta aplicación está disponible en el repositorio de Spotify showcase. Gracias por tenernos.

Genial. Entonces, brevemente, nos hemos quedado sin tiempo pero desafortunadamente no llegamos a hablar de toda la historia de suspense. También lanzamos otros dos hooks en Apollo client 3.8, use background query y use read query para ayudar a evitar cascadas de solicitudes. Así que si estás interesado en ellos, consulta nuestra documentation o ven a hablar con nosotros después de nuestra masterclass aquí. Sí, y mirando hacia el futuro, actualmente estamos trabajando en la próxima versión menor de Apollo client 3.9, en la que hemos planeado algunas nuevas APIs emocionantes, como una versión de suspense del hook use fragment, y también una versión lazy de use background query que estamos llamando use interactive query para precargar, prebuscar data en alguna interacción del usuario. Si te gustó la demostración que viste aquí hoy y quieres jugar con ella tú mismo, no dudes en ir a este repositorio, la organización Apollo GraphQL, el Spotify showcase, el código de esta aplicación completa vive allí. Y estamos planeando usar esto como una herramienta de enseñanza y una forma de mostrar algunas de las mejores prácticas de Apollo client, pero también como mantenedores, vamos a usarlo para poner a prueba nuestras propias APIs para realmente tener una idea de cómo es usarlo en una aplicación compleja. Pero con eso, muchas gracias por tenernos aquí. Sí, gracias.

QnA

Pruebas de Suspense y Límite de Suspense Único

Short description:

Para probar suspense en un componente, se pueden utilizar herramientas de prueba de React populares como testing library. La filosofía es probar la aplicación como los usuarios esperarían, por lo que el estado de carga permanece igual. El uso de un límite de suspense único en el nivel superior puede afectar negativamente el rendimiento percibido, pero se pueden agregar límites adicionales. No es necesario que cada componente tenga un estado de carga, y el patrón de estado de carga del menú del usuario es un azúcar sintáctico para no suspense.

Entonces, comencemos con el primero justo en el medio aquí. Vale. Entonces, el primero, ¿cómo procederías para testing suspense? Buena pregunta. Supongo que depende de, supongo que esta persona está hablando de, ¿cómo procederías para testing un componente que está usando suspense para renderizar su fallback? Y la respuesta es realmente usando las herramientas de testing que son súper populares y ubicuas en la React community, como testing library.

Sí, para mantener mi respuesta corta, ¿algo que agregar? Sí, solo agregaré allí, así que una de las filosofías de testing library es usar la aplicación como tus usuarios esperarían. Entonces, presumiblemente ya estás testing algún tipo de estado de carga en tu aplicación. ¿Sabes, mi componente renderiza cualquier spinner o texto de carga o lo que sea que tengas? Va a ser lo mismo. Es solo que tu código en ese componente se organizará un poco diferente. Pero si lo estás usando como una especie de caja negra, como la experiencia final del usuario, realmente no hay mucho que cambiar. Gracias.

Y esta puede ser nuestra última pregunta, pero de nuevo, podrás hablar con ellos alrededor de la esquina. Entonces, última pregunta, ¿cómo afecta el uso de un único límite de suspense en el nivel superior a cosas como SCP y LCP? ¿Y puede ser respondida en dos minutos? Sí, buena pregunta. Entonces, la respuesta corta es que probablemente no quieras solo un límite de suspense en tu aplicación. Sabes, tal vez hay un cierto tipo de aplicación que, sabes, donde realmente quieres esperar a que todas las solicitudes de red iniciales se resuelvan antes de mostrar algo a el usuario. el beneficio de poder usar esa API componible super Reacty que te permite simplemente componer estas cosas muy bien. Entonces, nuevamente, probablemente si tuvieras muchas solicitudes de red ocurriendo en tu aplicación y solo un límite de suspense, sí, eso definitivamente podría afectar negativamente tu percepción de performance en UX de carga, pero por eso es súper simple agregar límites adicionales. Sí. Creo que podemos meter una más. ¿Qué te parece? Hagámoslo. ¿Por qué no? Hagámoslo. Vale. Entonces, usaste un patrón de estado de carga del menú del usuario. ¿Cada componente tiene un estado de carga? ¿Cómo escala esto? Esto parece un azúcar sintáctico para no suspense. Sí, así es como realmente elegí estructurar esto para esta demostración porque es lo más fácil de recordar. No tuve que lidiar con las importaciones porque obviamente lleva tiempo escribir frente a todos ustedes. Entonces, realmente, diría que depende de ti, cualquier patrón que tengas hoy, nuevamente, el cambio más grande que tuvimos es que tomamos ese estado de carga que se renderizaba en nuestro componente y lo movimos a un límite de suspense. Pero no sé si notaste que cada uno de esos componentes que se renderizaban con el use query, si loading usaba ese mismo componente de estado de carga del menú del usuario dentro de allí. Así que realmente no cambié qué componente estaba usando. Solo lo moví al límite de suspense en lugar de renderizarlo en el componente. Pero de nuevo, eso es solo un patrón que elegí específicamente para esta masterclass.

Personalizando Estados de Carga

Short description:

Depende de ti. Sin embargo, eso funciona en tu aplicación. En esta aplicación, tenemos diferentes estados de carga, pero en tu caso, puede ser solo un componente. Depende. Gracias por tu charla.

Depende de ti. Sin embargo, eso funciona en tu aplicación. De nuevo, en esta aplicación en particular también, tenemos tantos estados de carga diferentes porque son pantallas de esqueleto, pero si tienes un solo spinner que usas en tu aplicación, puede ser solo un componente. Así que sí, de nuevo, es con el clásico, depende.

Wow. Son las 11.10 en punto. Muy bien. Muchas gracias. Y también somos el cronometrador. Así que muchas gracias por tu charla. ¿Podemos tener otra ronda de aplausos, por favor?

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

React Advanced Conference 2022React Advanced Conference 2022
25 min
A Guide to React Rendering Behavior
Top Content
React is a library for "rendering" UI from components, but many users find themselves confused about how React rendering actually works. What do terms like "rendering", "reconciliation", "Fibers", and "committing" actually mean? When do renders happen? How does Context affect rendering, and how do libraries like Redux cause updates? In this talk, we'll clear up the confusion and provide a solid foundation for understanding when, why, and how React renders. We'll look at: - What "rendering" actually is - How React queues renders and the standard rendering behavior - How keys and component types are used in rendering - Techniques for optimizing render performance - How context usage affects rendering behavior| - How external libraries tie into React rendering
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 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. 
React Advanced Conference 2022React Advanced Conference 2022
30 min
Using useEffect Effectively
Top Content
Can useEffect affect your codebase negatively? From fetching data to fighting with imperative APIs, side effects are one of the biggest sources of frustration in web app development. And let’s be honest, putting everything in useEffect hooks doesn’t help much. In this talk, we'll demystify the useEffect hook and get a better understanding of when (and when not) to use it, as well as discover how declarative effects can make effect management more maintainable in even the most complex React apps.
React Summit 2022React Summit 2022
20 min
Routing in React 18 and Beyond
Top Content
Concurrent React and Server Components are changing the way we think about routing, rendering, and fetching in web applications. Next.js recently shared part of its vision to help developers adopt these new React features and take advantage of the benefits they unlock.In this talk, we’ll explore the past, present and future of routing in front-end applications and discuss how new features in React and Next.js can help us architect more performant and feature-rich applications.
React Advanced Conference 2021React Advanced Conference 2021
27 min
(Easier) Interactive Data Visualization in React
Top Content
If you’re building a dashboard, analytics platform, or any web app where you need to give your users insight into their data, you need beautiful, custom, interactive data visualizations in your React app. But building visualizations hand with a low-level library like D3 can be a huge headache, involving lots of wheel-reinventing. In this talk, we’ll see how data viz development can get so much easier thanks to tools like Plot, a high-level dataviz library for quick & easy charting, and Observable, a reactive dataviz prototyping environment, both from the creator of D3. Through live coding examples we’ll explore how React refs let us delegate DOM manipulation for our data visualizations, and how Observable’s embedding functionality lets us easily repurpose community-built visualizations for our own data & use cases. By the end of this talk we’ll know how to get a beautiful, customized, interactive data visualization into our apps with a fraction of the time & effort!

Workshops on related topic

React Summit 2023React Summit 2023
170 min
React Performance Debugging Masterclass
Top Content
Featured WorkshopFree
Ivan’s first attempts at performance debugging were chaotic. He would see a slow interaction, try a random optimization, see that it didn't help, and keep trying other optimizations until he found the right one (or gave up).
Back then, Ivan didn’t know how to use performance devtools well. He would do a recording in Chrome DevTools or React Profiler, poke around it, try clicking random things, and then close it in frustration a few minutes later. Now, Ivan knows exactly where and what to look for. And in this workshop, Ivan will teach you that too.
Here’s how this is going to work. We’ll take a slow app → debug it (using tools like Chrome DevTools, React Profiler, and why-did-you-render) → pinpoint the bottleneck → and then repeat, several times more. We won’t talk about the solutions (in 90% of the cases, it’s just the ol’ regular useMemo() or memo()). But we’ll talk about everything that comes before – and learn how to analyze any React performance problem, step by step.
(Note: This workshop is best suited for engineers who are already familiar with how useMemo() and memo() work – but want to get better at using the performance tools around React. Also, we’ll be covering interaction performance, not load speed, so you won’t hear a word about Lighthouse 🤐)
React Advanced Conference 2021React Advanced Conference 2021
132 min
Concurrent Rendering Adventures in React 18
Top Content
Featured WorkshopFree
With the release of React 18 we finally get the long awaited concurrent rendering. But how is that going to affect your application? What are the benefits of concurrent rendering in React? What do you need to do to switch to concurrent rendering when you upgrade to React 18? And what if you don’t want or can’t use concurrent rendering yet?

There are some behavior changes you need to be aware of! In this workshop we will cover all of those subjects and more.

Join me with your laptop in this interactive workshop. You will see how easy it is to switch to concurrent rendering in your React application. You will learn all about concurrent rendering, SuspenseList, the startTransition API and more.
React Summit Remote Edition 2021React Summit Remote Edition 2021
177 min
React Hooks Tips Only the Pros Know
Top Content
Featured Workshop
The addition of the hooks API to React was quite a major change. Before hooks most components had to be class based. Now, with hooks, these are often much simpler functional components. Hooks can be really simple to use. Almost deceptively simple. Because there are still plenty of ways you can mess up with hooks. And it often turns out there are many ways where you can improve your components a better understanding of how each React hook can be used.You will learn all about the pros and cons of the various hooks. You will learn when to use useState() versus useReducer(). We will look at using useContext() efficiently. You will see when to use useLayoutEffect() and when useEffect() is better.
React Advanced Conference 2021React Advanced Conference 2021
174 min
React, TypeScript, and TDD
Top Content
Featured WorkshopFree
ReactJS is wildly popular and thus wildly supported. TypeScript is increasingly popular, and thus increasingly supported.

The two together? Not as much. Given that they both change quickly, it's hard to find accurate learning materials.

React+TypeScript, with JetBrains IDEs? That three-part combination is the topic of this series. We'll show a little about a lot. Meaning, the key steps to getting productive, in the IDE, for React projects using TypeScript. Along the way we'll show test-driven development and emphasize tips-and-tricks in the IDE.
React Advanced Conference 2021React Advanced Conference 2021
145 min
Web3 Workshop - Building Your First Dapp
Top Content
Featured WorkshopFree
In this workshop, you'll learn how to build your first full stack dapp on the Ethereum blockchain, reading and writing data to the network, and connecting a front end application to the contract you've deployed. By the end of the workshop, you'll understand how to set up a full stack development environment, run a local node, and interact with any smart contract using React, HardHat, and Ethers.js.
React Summit 2023React Summit 2023
151 min
Designing Effective Tests With React Testing Library
Top Content
Featured Workshop
React Testing Library is a great framework for React component tests because there are a lot of questions it answers for you, so you don’t need to worry about those questions. But that doesn’t mean testing is easy. There are still a lot of questions you have to figure out for yourself: How many component tests should you write vs end-to-end tests or lower-level unit tests? How can you test a certain line of code that is tricky to test? And what in the world are you supposed to do about that persistent act() warning?
In this three-hour workshop we’ll introduce React Testing Library along with a mental model for how to think about designing your component tests. This mental model will help you see how to test each bit of logic, whether or not to mock dependencies, and will help improve the design of your components. You’ll walk away with the tools, techniques, and principles you need to implement low-cost, high-value component tests.
Table of contents- The different kinds of React application tests, and where component tests fit in- A mental model for thinking about the inputs and outputs of the components you test- Options for selecting DOM elements to verify and interact with them- The value of mocks and why they shouldn’t be avoided- The challenges with asynchrony in RTL tests and how to handle them
Prerequisites- Familiarity with building applications with React- Basic experience writing automated tests with Jest or another unit testing framework- You do not need any experience with React Testing Library- Machine setup: Node LTS, Yarn