El caché de Apollo es tu amigo, si lo conoces

Rate this content
Bookmark

En esta charla, planeo discutir cómo funciona el caché de Apollo en la práctica, qué tan importantes son los ID en el proceso y cómo se puede aprovechar (a través de la forma en que se consulta/muta y a través del diseño del esquema). Además, quiero compartir algunos patrones de caché y mejores prácticas utilizadas en Shopify y más allá para resolver problemas.

23 min
17 Jun, 2022

Comments

Sign in or register to post your comment.

Video Summary and Transcription

Esta charla discute varios aspectos del caché de Apollo en GraphQL y Apollo Client 3. Cubre temas como las políticas de recuperación de caché, la normalización, las actualizaciones y la recolección de basura. Se enfatiza la importancia del almacenamiento y gestión adecuados de datos en el caché. La charla también explora los desafíos de gestionar listas y la necesidad de funciones de actualización personalizadas. En general, proporciona ideas para optimizar el rendimiento y la eficiencia del caché de Apollo en el desarrollo de software.

Available in English

1. Introducción a Apollo Cache

Short description:

Soy Raman Lally de Shopify, dando una charla sobre cómo hacer amigos con la caché de Apollo. Hemos estado utilizando GraphQL y pasando a Apollo Client 3. Comprender la caché y las políticas de búsqueda es crucial. La caché se almacena en memoria y se reconstruye con la aplicación. Es una representación de tus datos, no los datos reales. Las políticas de búsqueda determinan la recuperación de datos desde la caché o la red.

Así que soy Raman Lally. Estoy aquí desde Shopify y estoy dando una charla sobre cómo hacer amigos con la caché de Apollo. Ese fue mi único meme. Solo tenía espacio para uno, así que eso es más de mí. La razón por la que surgió esta charla es porque hemos estado utilizando GraphQL desde siempre y recién comenzamos a usar Apollo Client 3 y la gente se encontró con estos errores extraños y voy a hablar sobre uno. Pero quería hablar sobre cómo podemos evitar esos errores y conocer cómo funciona la caché es la mejor manera.

Entonces, alguien había creado esta consulta que extraía los metadatos de un producto y tenían esta consulta. No se ve exactamente así, pero había algo mal en esta consulta y esa segunda parte de datos simplemente no estaba llegando. ¿Verdad? La estaban consultando, no hay nada allí, y volveremos a esto en un minuto y veremos cómo podemos solucionarlo.

Entonces, ¿qué está sucediendo en la caché? ¿Qué hay exactamente allí? ¿Y dónde está? ¿Verdad? ¿Es un objeto de datos que estamos guardando en algún lugar? Estas son cosas que no sabía. Y ahora ustedes podrían saberlo. Está en memoria, como su nombre lo indica. Y ahí es exactamente donde se almacena. Cada vez que reconstruyas tu aplicación, se reconstruirá. Cada vez que actualices la página, volverá. No se guarda en ningún lugar, a menos que lo hayas guardado tú mismo. ¿Y qué hay dentro de ella? No es realmente tus datos. Es como una representación de tus datos. Toma los datos que obtuviste de tu consulta y almacenamos una versión de ellos. Antes de hablar de eso, quiero hablar de cómo obtenemos esos datos. Y eso son las políticas de búsqueda. Estas definen cuándo obtener tus datos de la caché y cuándo obtenerlos de la red. Hay seis de ellas y las voy a explicar rápidamente. Principalmente porque esto es una de las principales cosas que pueden causar un error en tu aplicación. Digamos que esperas obtener datos de la red de inmediato, o necesitas una nueva versión fresca. No esperas obtenerlos de la caché. Probablemente querrías intercambiarlos. Aquí está nuestra primera. Primero la caché, es nuestra primera.

2. Políticas de búsqueda de la caché de Apollo

Short description:

La caché tiene diferentes políticas de búsqueda: cache-and-network, network-only y cache-only. Cache-and-network recupera datos primero de la caché y luego los actualiza desde la red. Network-only obtiene datos de la red y actualiza la caché. Cache-only recupera datos solo de la caché. La política de búsqueda depende de la consistencia y frescura de los datos que necesitas.

Y es el predeterminado, y es muy simple. ¿Está toda tu data en la caché dorada? Si no lo está, vamos a ir a la red. Y la palabra clave aquí es toda. Entonces, si tienes una consulta idéntica, pero estás solicitando un campo adicional, lo hará de todos modos, porque todos esos data no están en la caché. Y luego, muy similar a esto, está solo la caché. Y lo mismo es cierto aquí, donde si toda esa data no está allí, te dará un error y no volverá. Y tenemos algunos otros como caching y networking. Entonces, este es interesante, porque va a buscarlo en tu caché y luego rellenar la caché desde la red, ¿verdad? Entonces, si tienes muchos datos que cambian con frecuencia y quieres que sean increíblemente consistentes, esta sería la forma de hacerlo. Y luego irá a la red, rellenará tu caché, pero siempre tendrás primero la caché. Y esto es muy similar, excepto que solo irá a la red y luego actualizará tu caché. Entonces, si necesitas obtener primero solo los datos actualizados y vas a esperar, algo como cargar y esperar, y luego lo guardaremos en la caché si vas a tener una consulta posterior, obténlo de allí. Y finalmente, solo la red. Muy simple, nada más ahí.

3. Normalización de la caché de Apollo

Short description:

Entonces tenemos nuestros datos y sabemos cuándo los obtenemos de la caché. La normalización es cómo se almacenan los datos en la caché. Los objetos se dividen y se les asignan identificadores únicos. El valor predeterminado es usar el nombre del tipo y el ID, pero se pueden usar identificadores personalizados. La caché es una estructura de datos aplanada, lo que facilita el acceso. La caché normalizada contiene referencias a objetos, lo que permite que varias consultas utilicen los mismos tipos de objetos.

Entonces tenemos nuestros data, y sabemos cuándo lo obtenemos, y sabemos cuándo lo obtenemos de la caché, pero ¿qué hay en la caché? ¿Cómo se almacenaron esos data? ¿Verdad? Dije que no es exactamente tu data, es solo una representación de ella. Y la normalización es cómo se almacenó. Entonces se normaliza en pasos, y hay tres, básicamente, en los que se puede descomponer. Nuestro primer paso es, cualquier objeto data que llegue, lo vamos a dividir. Y lo vamos a dividir en todas las entidades de objeto que podría ser. Donde, ya sabes, en un momento, creo que era cada objeto data que puede existir en tu aplicación se dividiría y se normalizaría, y eso sería realmente genial. Pero no es exactamente el caso.

Imagina que teníamos esta consulta realmente genial. Verás que esto es de una aplicación de demostración que escribí que en realidad no podré mostrarte, pero lo enlazaré al final. Y es realmente fea. Entonces, básicamente aquí, podemos ver que los tres objetos que se descomponen tienen una cosa en común, y es que todos son identificables de forma única. Y eso nos lleva al siguiente punto, donde el segundo paso es después de descomponer todos estos objetos, queremos darles identificadores únicos, ¿verdad? Y la forma predeterminada de hacerlo es simplemente usando el nombre del tipo y el ID. Entonces, si tu objeto tiene un campo de ID, se normalizaría, o intentarían normalizarlo. Pero eso es solo generalmente, porque es posible que no tengas un identificador que sea exactamente ID. En esa situación, usarías la API de campos clave. Entonces puedes definir tus propios identificadores, como, digamos, si tuvieras UID como identificador para un objeto, podrías usarlo directamente. También podrías usar múltiples campos anidados para crearlo. Pero este es el mismo concepto que usar ID y nombre del tipo, ¿verdad? Puedes generar el tuyo propio, y de esta manera, esos objetos también se normalizarían. De lo contrario, se normalizarían bajo su objeto principal. Entonces, en la raíz, solo tendrías la consulta. Entonces, si no tuvieras un identificador en ningún objeto, sería este gran objeto de cualquier consulta que llegara. Los tenemos todos descompuestos, los tenemos en estos objetos individuales que son identificables, y los vamos a guardar en esta estructura de data aplanada. Y queremos esa estructura de data aplanada porque es fácil de acceder y podemos hacerla lo más pequeña posible. Y esa es básicamente la idea, tomamos esa otra consulta, y esto es exactamente cómo se ve la caché normalizada. Entonces, si extrajeras la caché y la examinaras, lo cual voy a mostrarte en un minuto, esto es exactamente cómo se ve. Y puedes ver que eso, como... Todos estos objetos que tenían identificadores, en realidad no están dentro o anidados dentro de los otros objetos. Solo tenemos una referencia a ellos. Y en cualquier momento, si esta consulta necesitara obtener este objeto, lo obtendría de esta referencia.

4. Actualizaciones de la caché de Apollo

Short description:

El poder de la normalización se ve cuando varias consultas utilizan los mismos tipos de objetos. Las actualizaciones automáticas son geniales, pero a veces no funcionan como se espera. También discutiremos las actualizaciones no tan automáticas. Cuando los datos se normalizan y se almacenan en caché, pueden fusionarse o agregarse si ya existen datos. La fusión automática ocurre al actualizar una entidad única con su identificador y campos actualizados.

Pero la magia ocurre cuando tienes varias consultas que utilizan estos mismos tipos de objetos. Como, usamos tipos en todas partes. Simplemente estarán haciendo referencia al mismo objeto en la caché. Y ahí radica realmente el poder de esa normalización.

Estas son lavadoras. Así que esto fue mi improvisación sobre algo relacionado con la automatización, algo automático. No se me ocurrió nada mejor que esto. Pensé que tal vez una transmisión de automóvil también funcionaría. Pero en esencia, la idea es que tenemos nuestros data y vamos a obtener nuevos data después. ¿Verdad?

Y estoy seguro de que en algún momento has visto que si vuelves a consultar, los data se actualizan automáticamente. Y eso es realmente genial. Y nos encanta eso. Y las cosas automáticas son realmente geniales. Pero a veces las cosas automáticas no funcionan tan bien. Así que voy a meter esta camiseta en la lavadora y tiene una mancha. Y generalmente, todas mis manchas se lavan. Pero esta no se fue. Y creo que esto ya le había pasado a esta camiseta antes. Y era de arándano. Y era realmente fea. Así que pensé, bueno, sí. La lavadora es una porquería. Probablemente debería haberlo hecho a mano. Pero la lavadora no es una porquería, porque probablemente debería haber hecho algo antes de ponerla allí para que la función automática funcione mejor. Así que de eso vamos a hablar. A veces suceden actualizaciones no tan automáticas.

Entonces, cada vez que los data llegan a tu aplicación, se normalizan y se almacenan en caché, sucederá una de dos cosas si ya hay data allí. Se fusionarán o se agregarán. Solo hay dos opciones. Entonces, ¿cuándo se fusiona automáticamente? ¿Cuáles son esos escenarios en los que sucede y funciona, y estamos realmente contentos con eso? El primero es si solo estás actualizando una entidad única y devuelves esa entidad con su identificador y sus campos actualizados.

5. Actualización de la caché de Apollo

Short description:

Los objetos se pueden fusionar fácilmente por su identificador. Si tienes una lista de entidades, necesitas devolver toda la colección para actualizar cada una de ellas. A veces, los datos de respuesta no están relacionados con la actualización deseada, lo que requiere una función de actualización personalizada. Las listas son difíciles de gestionar, especialmente cuando no se devuelve la lista completa o cuando cambia el orden. Agregar o eliminar objetos de una lista también requiere una función de actualización personalizada. La caché no asume cómo deben almacenarse los datos ni los examina internamente.

Es realmente simple de hacer. Nuevamente, como vimos, todos esos objetos están en este hash. Podemos agarrarlos fácilmente por su identificador y fusionar estos nuevos campos. Y esto es lo que sucederá con mayor frecuencia.

Pero el segundo caso es si tienes una lista o una colección de entidades y devuelves todas ellas con todos sus identificadores y todos los campos que deben actualizarse. Entonces, esto no funciona si devuelves, digamos, algunos de ellos o solo uno de ellos. Debes devolver toda la colección para actualizar cada uno de ellos. Así que hablemos de cuando no funciona, porque estos son los casos en los que nos encontramos y es una situación realmente fea.

Entonces, primero, supongamos que tu respuesta data que está llegando no está relacionada con la actualización que deseas que ocurra. Así que sé que hubo algunas situaciones en las que teníamos un objeto que íbamos a marcar como favorito, como un producto que se estaba marcando como favorito. Y lo marcaste como favorito, la mutación se envía, vuelve. Devuelves el ID y el estado de favorito, y eso se actualiza y se actualizará ese producto dondequiera que se esté utilizando en esa interfaz de usuario. Lo que no se actualizará es cuántos productos están marcados como favoritos. Digamos que tenías una interfaz de usuario que mostraba el número de objetos marcados como favoritos. Puede estar relacionado, pero no es el mismo data. Entonces, en este escenario, tendrías que escribir tu propia función de actualización y actualizar ese data tú mismo, aunque te parezca relacionado.

Luego, el resto de estos se trata de listas, porque eso es realmente lo más difícil de gestionar, donde, nuevamente, si no devuelves toda la lista de objetos actualizados, no obtendrás esa actualización automática. Lo mismo ocurre si cambia el orden. Entonces, si enviaras, digamos, objetos en el orden 1, 2, 3, 4, y lo cambias a 1, 2, 4, 3, cuando regrese, los objetos siguen siendo los mismos. Lo único que cambia es el orden. No se reflejará en tu interfaz de usuario. Eso es algo que tendrías que escribir automáticamente. Y principalmente porque la caché no hace suposiciones sobre cómo quieres almacenar tus data o cómo debería verse tu data dentro de la caché. Esos objetos son idénticos. Y lo único a lo que hace referencia son las referencias a esos objetos. Y finalmente, agregar o eliminar cosas, lo cual también es realmente molesto, porque si fuera a desmarcar algo como favorito, puedo actualizar el estado de favorito de ese objeto, pero no puedo eliminarlo de una lista de objetos favoritos. Eso es algo para lo que tendrías que escribir una función de actualización, porque, nuevamente, no sabe que no puedes devolver algo de una mutación y decir, OK, sí, ahora elimina esto por mí. Solo puedes devolver algo. Entonces, nuevamente, las funciones de actualización existen para hacer eso, pero en estos escenarios, como, puede ser un error si no esperas que se actualice automáticamente. Y definitivamente nos hemos encontrado con eso.

6. Problema y solución de la caché de Apollo

Short description:

El problema ocurrió porque el identificador para los metadatos del producto y los metadatos eran los mismos. Mientras que los objetos se normalizaban dentro de la caché, el valor sin un ID no podía ser normalizado. Agregar un ID al valor resolvió el problema y permitió una normalización adecuada.

Volveremos a esto, porque ahora hemos hablado de un par de cosas que entrarían en juego si quisiéramos resolver este problema. Pero básicamente la idea aquí era que los metadatos del producto son del mismo tipo que este tipo de metadatos aquí abajo. Y luego esta persona estaba consultando esto, y decía, oh, como, slug es indefinido. No sé por qué slug es indefinido. Y esto se debe principalmente a que el identificador para los metadatos del producto y el identificador para los metadatos eran los mismos, ¿verdad? Entonces esos objetos se normalizaron dentro de la caché. Y esperarías que sus hijos también lo estuvieran. El problema es que 'values' tiene un ID y este valor no tiene un ID. Y lo que le sucedió a este valor es que se intentó normalizar, pero no se pudo. Y el objeto del otro valor fue el que se guardó dentro de este objeto totalmente normalizado. Entonces, la forma de resolver esto es simplemente agregarle un ID. Y ahora puedo encontrarlo, pueden actualizarlo y ahora pueden ser, ya sabes, normalizados correctamente.

7. Garbage Collection and Eviction in Apollo

Short description:

En esta parte, discutiremos la recolección de basura y cómo funciona en Apollo. A diferencia de JavaScript, donde la recolección de basura ocurre en segundo plano, en Apollo interactuamos manualmente con ella. La recolección de basura limpia los objetos no referenciados en la caché y devuelve los IDs de los elementos recolectados. Utilizaremos un ejemplo de aplicación ficticia para demostrar el impacto de las mutaciones en el tamaño de la caché y los identificadores.

Ahora pasamos a la última parte, y la parte que más me emocionaba, que era la recolección de basura y cómo funciona la evicción. Estoy seguro de que todos han encontrado la recolección de basura en algún momento. Me di cuenta después de que en realidad es reciclaje, y no basura. Estaba pensando en poner algo encima, pero no lo hice.

En general, la recolección de basura, intentamos recuperar memoria de nuestra aplicación, y en JavaScript, eso generalmente ocurre en segundo plano, ¿verdad? No tenemos que interactuar manualmente con ella. En Apollo, sí tenemos que interactuar manualmente con ella. Y así es como lo haríamos. Intenté hacerlo lo más pequeño posible pero aún legible, ¿verdad? Pero principalmente porque es tan pequeño, ¿verdad? Llamarías a esta recolección de basura para limpiar cualquier objeto no referenciado en tu caché. Y mostraremos cómo se verá eso en un segundo.

Pero lo otro es que esto devolverá los IDs de todo lo que se haya recolectado. Aquí está esa aplicación ficticia de la que hablaba. Usando las mismas consultas que antes. Así que hay un servidor GraphQL. Lo estamos consultando para todos esos píxeles, incluyendo todos los espacios en blanco. Y cada uno de ellos es identificable individualmente. Por lo tanto, ocupa... Puedes ver que simplemente imprimí ese tamaño de caché. Ese no es el tamaño real de la caché. Es solo la cantidad de claves que había en la caché. Pero es solo para representar cuán grande podría ser la caché en ese momento. Y tiene tantos elementos. Y la idea era que hay como un... Dado que todos estos tienen IDs, todos son direccionables, todos se están normalizando. Digamos que vamos a cambiar el color de Pikachu a naranja. Puede que notes que la caché ahora es el doble de grande. O más. ¿Verdad? Entonces, el problema aquí es que hicimos esta mutación... Este es un ejemplo muy ficticio. Pero básicamente todos esos identificadores cambiaron. O la gran mayoría de ellos.

8. Recolección de Basura y Retención de Objetos

Short description:

Y volvieron y no pudieron fusionarse. ¿Qué pasó? Tuvieron que ser agregados. Todos esos otros objetos todavía están ahí. Simplemente no son accesibles a través del objeto raíz real. No los necesitamos. Nuestra interfaz de usuario no los necesita. Pero siguen ahí y ocupan espacio. Esa es realmente la razón principal por la que queremos deshacernos de estas cosas.

Y volvieron y no pudieron fusionarse. ¿Qué pasó? Tuvieron que ser agregados. ¿Verdad? Todos esos otros objetos todavía están ahí. Simplemente no son accesibles a través del objeto raíz real. No los necesitamos. Nuestra interfaz de usuario no los necesita. Pero siguen ahí y ocupan espacio. Esa es realmente la razón principal por la que queremos deshacernos de estas cosas.

Entonces digamos que lo ejecutamos. Y esto es, nuevamente, una versión más rudimentaria de todos esos otros data. ¿Cómo recopilamos todos estos elementos que no se están referenciando? La idea es que el recolector de basura eche un vistazo a la caché normalizada y de forma recursiva recorra cada nodo que existe dentro de la caché hasta encontrar todos tus nodos hoja al final. Y cualquier cosa que no haya sido visitada será eliminada.

Entonces esta es nuestra nueva consulta. La que tiene todo el color naranja con todos esos nuevos identificadores. Y esta es nuestra consulta original que tenía el color naranja. Y puedes ver que ya no está siendo referenciada por root, porque ya no estamos usando ese data. No es nuestra consulta principal. Pasaríamos por todos estos nodos, boom, todos están bien. Y los que no fueron visitados serán eliminados por el recolector de basura.

Entonces, digamos que había un objeto específico que queríamos conservar o queríamos hacer que incluso si no es accesible, no se elimine, usaríamos una API de retención para esto. Pero realmente lo que sucede dentro de la caché cuando retienes algo es que lo agregamos a este ID raíz adicional. Entonces, dentro de la caché normalizada hay un campo separado, supongo, para hacer un seguimiento de todos estos identificadores. Y lo curioso que noté cuando estaba trabajando con esto fue que si alguna vez escribes un fragmento, como si alguna vez usas el write fragment o write query, esos objetos que escribes directamente también se retienen automáticamente. Entonces, si estabas escribiendo todos los objetos, como un montón de objetos aleatorios en tu caché, y estabas ejecutando el recolector de basura, no se están recolectando, es porque todos se estaban reteniendo por defecto, y es porque los alteraste directamente. Entonces, si quisieras deshacerte de ellos, puedes liberarlos después del hecho.

Entonces, más o menos se verá así. Digamos que queríamos conservar el cachete. Creo que eso es lo que lo llamo aquí, ¿verdad? Sí. Y lo que sucederá es que el recolector de basura recorrerá, visitará todos esos nodos que conoce, luego visitará todos estos nodos a los que has hecho referencia dentro de tu retención, y boom, no se deshará de esos chicos malos. Entonces, la última parte es que lo que el recolector de basura no va a eliminar es cualquier objeto que sea accesible, ¿verdad? Es posible que desees deshacerte de ellos manualmente.

9. Evicción y Recolección de Basura

Short description:

Agregar y eliminar cosas manualmente, API de evicción para eliminar objetos de la caché, ejecutar el recolector de basura para eliminar objetos no referenciados.

Y hablamos de esto antes, donde agregar y eliminar cosas es algo que debes hacer manualmente en lugar de que ocurra automáticamente cuando vuelves a consultar. Entonces, nuevamente, ahí es donde entra en juego la API de evicción. Por lo tanto, puedes eliminar directamente un objeto completo de la caché si así lo deseas. El único problema es, supongamos que te deshiciste de esa raíz que estaba referenciando todos esos otros nodos que vimos antes, por lo que tenía una referencia a cada uno de esos objetos. Teóricamente, ya nada tiene una referencia a esos objetos si te deshiciste de ese objeto de nivel superior. Entonces, si alguna vez vas a usar esto, tendrías que ejecutar el recolector de basura después del hecho para deshacerte de todos esos objetos que ya no se pueden referenciar.

10. Ciclo del Objeto en la Caché de Apollo

Short description:

Puedes eliminar campos específicos para tener un mayor control sobre las actualizaciones de consulta. Hemos recorrido el ciclo de obtención, normalización, actualización y recolección/eliminación de objetos. Hay demos disponibles como referencia.

Y luego puedes ir un paso más allá y simplemente eliminar campos específicos si así lo deseas. Lo cual te brinda mucho más poder para actualizar las consultas después de que se produzca un cambio. Y ahí lo tienes realmente. Hemos recorrido el ciclo de un objeto desde su obtención hasta su normalización dentro de la caché hasta cómo lo actualizaríamos o cómo se actualizarían automáticamente esas cosas y finalmente a la recolección y eliminación de los mismos. No pude escribir la última línea porque no encaja de nuevo en la obtención. Así que me sentí realmente incómodo al respecto. Iba a mostrar la demostración pero no tengo tiempo para eso. He enlazado todas las demos realmente feas que escribí y solo tienen ejemplos de todo de lo que estaba hablando aquí. Así que si alguien quiere echarles un vistazo, puedo proporcionar los enlaces.

QnA

Estrategia de Caché y Evolución

Short description:

Hablando de por consulta, ¿es la estrategia de caché algo que debes decidir antes de comenzar o puede evolucionar con el tiempo? Para nosotros, definitivamente evolucionó con el tiempo. No quieres comprometerte completamente antes de comenzar tu aplicación. Las cosas pueden cambiar muy rápidamente, ¿verdad? Y lo harán.

Y luego un poco de publicidad descarada. Gracias. Gracias, Raman.

Hagamos algunas preguntas. Llamo a mis recogidas de Uber recolección de basura. ¿Qué política de obtención recomiendas usar para una aplicación de página única estándar? La predeterminada. Caché primero, honestamente. Diría que cubriría la gran mayoría de los escenarios que deseas cubrir. No creo que puedas tener problemas al usar esa en comparación con las demás. Pero querrías usar una combinación. Puedes hacerlo por consulta. Si tienes 10 consultas, algunas de ellas solo querrán obtener datos de la caché o generar un error.

Hablando de por consulta, ¿es la estrategia de caché algo que debes decidir antes de comenzar o puede evolucionar con el tiempo? Para nosotros, definitivamente evolucionó con el tiempo. No quieres comprometerte completamente antes de comenzar tu aplicación. Las cosas pueden cambiar muy rápidamente, ¿verdad? Y lo harán. Y lo harán.

Así que prepárate. ¿Has tenido alguna historia de terror con la caché? Yo tengo una. Y esa es la razón principal por la que escribí esto en primer lugar. Drama. Teníamos esta página de inicio con todos estos carruseles en ella. Y ya era una mala idea, porque había tres carruseles en esta página de inicio y no teníamos ninguna entrada en eso. Pero todos compartían datos de productos similares. Y lo que sucedía es que podías marcar como favoritos productos dentro del carrusel. Y no nos dimos cuenta de este problema hasta más tarde, pero debido a la forma en que nuestras mutaciones estaban escritas, solo devolvían si algo realmente se marcaba como favorito o no. No su ID y el estado de favorito. Así que marcabas como favorito un objeto en el primer carrusel y en los carruseles dos y tres, no estaban marcados como favoritos. Y alguien lo mencionó, y pensamos, esto es una gran falla en nuestra estrategia de mutaciones design. Así que la gente simplemente se sumergió, y descubrimos, oh, podríamos actualizar automáticamente todo.

Refetching Queries and Manual Garbage Collection

Short description:

Consideramos volver a consultar las consultas para las actualizaciones, pero nos dimos cuenta de que no es un enfoque adecuado. La pregunta de cómo llegamos aquí y la importancia de los favoritos. Cuándo ejecutar la recolección de basura manualmente depende de la aplicación. Si se esperan objetos huérfanos, se puede hacer después de cualquier consulta. Raman estará disponible para más discusión.

Alguien sugirió que podríamos simplemente volver a consultar todas estas consultas para asegurarnos de que todo se actualice cada vez. Pero ya sabes, esa es una forma horrible de hacerlo. Así que no queríamos ir por ese camino.

¿Dirías que los favoritos fueron lo que te trajo aquí? ¿Y mira dónde estás ahora? Sí, mírame ahora.

Tenemos otra pregunta, que es, ¿cuándo deberíamos ejecutar la recolección de basura manualmente en lugar de hacerlo automáticamente? Supongo que depende de tu aplicación. Como habrá muchas aplicaciones en las que realmente no necesitas ejecutarla manualmente. Como no terminarás con un montón de objetos huérfanos antes de que alguien cambie la página o se mueva a otro lugar. Pero si sabías que ibas a hacerlo, y sabías que ibas a descartar objetos así podrías ejecutarlo, ya sabes, después de cualquier consulta. No es muy intensivo en tiempo, ¿verdad? Genial.

Como recordatorio, Raman estará en los puestos de los oradores justo afuera después de esto si quieres hablar con él o hacer más preguntas, otro gran aplauso. Gracias por estar aquí con nosotros.

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 2021React Advanced Conference 2021
39 min
Don't Solve Problems, Eliminate Them
Top Content
Humans are natural problem solvers and we're good enough at it that we've survived over the centuries and become the dominant species of the planet. Because we're so good at it, we sometimes become problem seekers too–looking for problems we can solve. Those who most successfully accomplish their goals are the problem eliminators. Let's talk about the distinction between solving and eliminating problems with examples from inside and outside the coding world.
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 Advanced Conference 2021React Advanced Conference 2021
47 min
Design Systems: Walking the Line Between Flexibility and Consistency
Top Content
Design systems aim to bring consistency to a brand's design and make the UI development productive. Component libraries with well-thought API can make this a breeze. But, sometimes an API choice can accidentally overstep and slow the team down! There's a balance there... somewhere. Let's explore some of the problems and possible creative solutions.
React Summit 2023React Summit 2023
23 min
React Concurrency, Explained
React 18! Concurrent features! You might’ve already tried the new APIs like useTransition, or you might’ve just heard of them. But do you know how React 18 achieves the performance wins it brings with itself? In this talk, let’s peek under the hood of React 18’s performance features: - How React 18 lowers the time your page stays frozen (aka TBT) - What exactly happens in the main thread when you run useTransition() - What’s the catch with the improvements (there’s no free cake!), and why Vue.js and Preact straight refused to ship anything similar
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!

Workshops on related topic

React Summit 2023React Summit 2023
170 min
React Performance Debugging Masterclass
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 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 Summit 2023React Summit 2023
151 min
Designing Effective Tests With React Testing Library
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
GraphQL Galaxy 2021GraphQL Galaxy 2021
140 min
Build with SvelteKit and GraphQL
Top Content
Featured WorkshopFree
Have you ever thought about building something that doesn't require a lot of boilerplate with a tiny bundle size? In this workshop, Scott Spence will go from hello world to covering routing and using endpoints in SvelteKit. You'll set up a backend GraphQL API then use GraphQL queries with SvelteKit to display the GraphQL API data. You'll build a fast secure project that uses SvelteKit's features, then deploy it as a fully static site. This course is for the Svelte curious who haven't had extensive experience with SvelteKit and want a deeper understanding of how to use it in practical applications.

Table of contents:
- Kick-off and Svelte introduction
- Initialise frontend project
- Tour of the SvelteKit skeleton project
- Configure backend project
- Query Data with GraphQL
- Fetching data to the frontend with GraphQL
- Styling
- Svelte directives
- Routing in SvelteKit
- Endpoints in SvelteKit
- Deploying to Netlify
- Navigation
- Mutations in GraphCMS
- Sending GraphQL Mutations via SvelteKit
- Q&A
React Advanced Conference 2022React Advanced Conference 2022
95 min
End-To-End Type Safety with React, GraphQL & Prisma
Featured WorkshopFree
In this workshop, you will get a first-hand look at what end-to-end type safety is and why it is important. To accomplish this, you’ll be building a GraphQL API using modern, relevant tools which will be consumed by a React client.
Prerequisites: - Node.js installed on your machine (12.2.X / 14.X)- It is recommended (but not required) to use VS Code for the practical tasks- An IDE installed (VSCode recommended)- (Good to have)*A basic understanding of Node.js, React, and TypeScript