¿Cómo implementar patrones de fetching en Next.js?
Next.js ofrece poderosas herramientas para el data fetching en aplicaciones, permitiendo implementar patrones de fetching secuencial y paralelo. Estos patrones optimizan la manera en que se obtienen y manejan los datos desde múltiples servicios, mejorando la eficiencia y velocidad de tu aplicación. Aprender a usarlos adecuadamente es esencial para cualquier desarrollador web que busque mejorar el rendimiento de sus proyectos.
¿Cómo estructurar los endpoints en Next.js?
Para implementar diferentes patrones de fetching, es esencial estructurar bien los endpoints en tu proyecto Next.js. Si planeas consumir datos de más de un endpoint, se recomienda organizar tus servicios de manera que cada tema o funcionalidad tenga su propio archivo.
Por ejemplo, para trabajar con productos y colecciones de una tienda en línea utilizando la API de Shopify, puedes crear un archivo product.ts y otro collections.ts. Esto facilita el mantenimiento y actualización de los endpoints:
¿Qué diferencias hay entre fetching paralelo y secuencial?
Fetching paralelo: Permite realizar múltiples solicitudes al mismo tiempo, sin que una dependa de la otra. Es ideal para obtener datos que no están relacionados o bloqueados entre sí, como en el caso al obtener productos y colecciones por separado. Esto mejora el tiempo de respuesta de tu aplicación.
Fetching secuencial: Las solicitudes se realizan una detrás de otra, y una no comienza hasta que otra ha terminado. Esto es útil cuando un dato depende de otro. Por ejemplo, si necesitas obtener un producto específico utilizando un ID que primero debes obtener de una lista general de productos, entonces el fetching se realizaría de manera secuencial.
¿Cómo integrar navegaciones dinámicas con datos en Next.js?
Una vez que tienes los datos listos, puedes utilizarlos para crear elementos de navegación dinámicos, como menús y listas de categorías. Una forma efectiva de hacerlo es implementando un componente de navegación usando los datos de colecciones:
Colocar el componente de navegación en el layout general de la aplicación asegura que estará siempre disponible y no necesitas repetirlo en cada página.
¿Cuáles son las consideraciones de rendimiento en Next.js?
Next.js destaca en su manejo del fetching gracias a su sistema de caché integrado. Esto significa que si realizas la misma llamada varias veces dentro de alguna sección de tu aplicación, Next.js se encarga de cachear la respuesta y redistribuirla, sin necesidad de realizar múltiples requests a la API externa. Esto no solo reduce la carga en el servidor, sino que también mejora drásticamente el rendimiento de tu aplicación, y es una de las razones por las que es una de las frameworks más recomendadas para proyectos avanzados.
Para mantener un rendimiento óptimo:
Use el sistema de caché de Next.js de manera eficiente.
Planifica tus endpoints y utiliza fetching paralelo siempre que sea posible.
Considera movimientos dinámicos en el layout en lugar de page-level data fetching para elementos comunes en toda la aplicación.
Al aplicar estos consejos y técnicas, podrás tener aplicaciones web Next.js rápidas y eficientes, listas para escalar y satisfacer las demandas de usuarios modernos. ¡Sigue explorando y mejorando tus habilidades en React y Next.js!
Next.js extiende el fetch nativo para permitir configurar como se cachean y revalidan los datos. Pero no modifica en ningún momento el comportamiento de async y await. Cuando se hacen peticiones de esta forma (dentro del mismo componente):
no se están haciendo de forma paralela, se está haciendo de forma secuencial. Primero pide los productos y espera hasta que se tiene la respuesta para ejecutar la siguiente línea de código, que es donde se lanza la petición de las colecciones.
Para que realmente se lancen las peticiones de forma paralela habría que utilizar un Promisse.all()
Totalmente de acuerdo. 👍🏻
Detalles que es mejor estar atentos, también pasó similar explicando el componente <Image /> con eso del lazy loading con la propiedad "priority", pero bueno, se aclara y se aprende del resto.
En Next.js, el fetching secuencial y fetching paralelo se refieren a dos enfoques diferentes para realizar solicitudes de datos desde una API u otra fuente externa durante el proceso de renderizado de una página o componente.
1. Fetching Secuencial
El fetching secuencial es un enfoque en el que las solicitudes de datos se realizan una tras otra, en un orden específico. Cada solicitud espera a que la anterior se complete antes de comenzar. Esto puede ser necesario cuando las solicitudes dependen entre sí, es decir, cuando el resultado de una solicitud es necesario para realizar la siguiente.
Ejemplo de Fetching Secuencial:
En este ejemplo, la segunda solicitud depende del resultado de la primera. Por lo tanto, la segunda solicitud no comenzará hasta que la primera haya finalizado.
2. Fetching Paralelo
El fetching paralelo es un enfoque en el que varias solicitudes de datos se realizan al mismo tiempo, sin esperar a que se completen las otras solicitudes. Este enfoque es más eficiente en términos de tiempo cuando las solicitudes no dependen entre sí, ya que puede reducir el tiempo total de espera.
Ejemplo de Fetching Paralelo:
En este ejemplo, ambas solicitudes (fetch('https://api.example.com/data1') y fetch('https://api.example.com/data2')) se inician simultáneamente. Luego, Promise.all espera a que ambas se completen antes de continuar.
Comparación y Uso en Next.js
Fetching Secuencial es útil cuando tienes dependencias entre los datos que estás recuperando. Sin embargo, puede ser más lento si hay varias solicitudes, ya que el tiempo de espera se acumula.
Fetching Paralelo es ideal cuando las solicitudes no tienen dependencias entre sí y necesitas optimizar el tiempo de respuesta. Es más eficiente en términos de rendimiento, ya que todas las solicitudes se ejecutan simultáneamente.
Uso en Next.js
En Next.js, puedes aplicar ambos enfoques dependiendo de la lógica de tu aplicación. Si usas funciones como getServerSideProps, getStaticProps, o dentro de componentes, puedes optar por hacer fetching secuencial o paralelo según lo que necesites.
Por ejemplo, en getServerSideProps:
En este ejemplo, se realiza fetching paralelo para optimizar el tiempo de carga
excelente gracias, esto es nuevo para mi 🤍
Next.js extiende el fetch nativo para permitir configurar como se cachean y revalidan los datos. Pero no modifica en ningún momento el comportamiento de async y await. Cuando se hacen peticiones de esta forma:
no se están haciendo de forma paralela, se está haciendo de forma secuencial. Primero pide los productos y espera hasta que se tiene la respuesta para ejecutar la siguiente línea de código que es donde se lanza la petición de las colecciones.
Para que realmente se lancen las peticiones de forma paralela habría que utilizar un Promisse.all()
No es paralelo el codigo del ejemplo con awaits, seria paralelo si no tuviese el await, justamente el await bloquea la ejecucion hasta que termine y luego ejecuta la siguiente linea. En este caso, hasta que no se terminen de obtener los articulos, no se obtienen las categorias.
importAlbumsfrom'./albums'asyncfunctiongetArtist(username: string){const res =awaitfetch(`https://api.example.com/artist/${username}`)return res.json()}asyncfunctiongetArtistAlbums(username: string){const res =awaitfetch(`https://api.example.com/artist/${username}/albums`)return res.json()}exportdefaultasyncfunctionPage({params:{ username },}:{params:{username: string }}){// Initiate both requests in parallelconst artistData =getArtist(username)const albumsData =getArtistAlbums(username)// Wait for the promises to resolveconst[artist, albums]=awaitPromise.all([artistData, albumsData])return(<><h2>{artist.name}</h2><Albums list={albums}></Albums></>)}```https://nextjs.org/docs/app/building-your-application/data-fetching/patterns
Esta es la verdadera forma para hacer fetching paralelo, no el ejemplo de la clase...
import Albums from './albums' async function getArtist(username: string) { const res = await fetch(`https://api.example.com/artist/${username}`) return res.json()} async function getArtistAlbums(username: string) { const res = await fetch(`https://api.example.com/artist/${username}/albums`)return res.json()}exportdefaultasyncfunctionPage({params:{ username },}:{params:{username: string }}){// Initiate both requests in parallel const artistData = getArtist(username) const albumsData = getArtistAlbums(username) // Wait for the promises to resolve const \[artist, albums] = await Promise.all(\[artistData, albumsData]) return ( <> \<h2>{artist.name}\</h2> \<Albums list={albums}>\</Albums> \</> )}
punto para tener en cuenta cuando se expone la api con next js, aumenta la latencia en la petición
Si utilizo axios para las llamadas a la api este cache de next tambien funcionaria?
🧪 Cuándo usar cada recurso de Nextjs y Reactjs:
Necesitás compartir datos entre componentes en el cliente➡️ Usa Context y Provider
Querés mejorar el rendimiento cargando datos del servidor➡️ Usa la caché de Next.js
Los datos cambian con frecuencia en el cliente➡️ Usa useState / useReducer + Context
Los datos son estáticos o cambian poco➡️ Usa caché de fetch() y cache()
Patrones de fetching secuencial y paralelo en Next.js
En Next.js, existen dos patrones principales para recuperar datos de forma asíncrona: fetching secuencial y fetching paralelo.
Fetching secuencial:
En el fetching secuencial, las solicitudes de datos se realizan una tras otra, en orden. Esto significa que la segunda solicitud no se iniciará hasta que la primera haya finalizado. Este patrón es útil para situaciones en las que necesitas que los datos se recuperen en un orden específico.
Fetching paralelo:
En el fetching paralelo, las solicitudes de datos se realizan simultáneamente. Esto significa que todas las solicitudes se iniciarán al mismo tiempo, y las respuestas se procesarán a medida que estén disponibles. Este patrón es útil para situaciones en las que necesitas recuperar datos de múltiples fuentes al mismo tiempo.
Tambien podriamos saltarnos el guardar los valores transformados en una variable y retornarlos directamente como resultado de el metodo .map()
Tambien podriamos saltarnos el guardar los valores transformados en una variable y retornarlos directamente como resultado de el metodo .map()const { smart_collections } = await response.json();
return smart_collections.map((collection: any) => ({
id: collection.id,
title: collection.title,
handle: collection.handle
}))