Composición, Caché y Arquitectura en Next.js moderno

VVercel
컴퓨터/소프트웨어

Transcript

00:00:00(Música animada) - Bueno, hola a todos.
00:00:06Mi nombre es Aurora.
00:00:07Soy desarrolladora web de Noruega.
00:00:09Trabajo como consultora en Crane Consulting y también estoy desarrollando activamente con el enrutador de aplicaciones de Next.js en mi proyecto de consultoría actual.
00:00:16Hoy les enseñaré patrones sobre composición,
00:00:18almacenamiento en caché y arquitectura en Next.js moderno que les ayudarán a garantizar la escalabilidad y el rendimiento.
00:00:24Permítanme primero repasar el concepto más fundamental para esta charla: la renderización estática y dinámica.
00:00:30Los encontramos ambos en el enrutador de aplicaciones de Next.js.
00:00:33La renderización estática nos permite construir sitios web más rápidos porque el contenido pre-renderizado puede ser almacenado en caché y distribuido globalmente,
00:00:39asegurando que los usuarios puedan acceder a él más rápidamente.
00:00:42Por ejemplo, el sitio web de Next.js Conf.
00:00:46La renderización estática reduce la carga del servidor porque el contenido no tiene que ser generado para cada solicitud de usuario.
00:00:51El contenido pre-renderizado también es más fácil de indexar para los rastreadores de motores de búsqueda,
00:00:56ya que el contenido ya está disponible al cargar la página.
00:00:58La renderización dinámica,
00:00:59por otro lado,
00:01:00permite que nuestra aplicación muestre datos en tiempo real o actualizados con frecuencia.
00:01:05También nos permite servir contenido personalizado,
00:01:07como paneles de control y perfiles de usuario.
00:01:09Por ejemplo, el panel de control de Vercel.
00:01:12Con la renderización dinámica,
00:01:13podemos acceder a información que solo se puede conocer en el momento de la solicitud.
00:01:16En este caso,
00:01:17qué usuario está accediendo a su panel de control,
00:01:19que soy yo.
00:01:20Hay ciertas API que pueden hacer que una página se renderice dinámicamente.
00:01:25El uso de las props `params` y `search params` que se pasan a las páginas o sus hooks equivalentes provocará la renderización dinámica.
00:01:32Sin embargo,
00:01:32con `params`,
00:01:33podemos predefinir un conjunto de páginas pre-renderizadas usando `static params` genéricos,
00:01:36y también podemos almacenar en caché las páginas a medida que son generadas por los usuarios.
00:01:40Además,
00:01:41leer las cookies y los encabezados de las solicitudes entrantes hará que la página opte por la renderización dinámica.
00:01:46A diferencia de `params`,
00:01:47sin embargo,
00:01:48intentar almacenar en caché o pre-renderizar algo usando encabezados o cookies generará errores durante la compilación porque esa información no se puede conocer de antemano.
00:01:56Por último,
00:01:56usar `fetch` con una configuración de caché de datos `no store` también forzará la renderización dinámica.
00:02:00Así que estas son algunas,
00:02:02hay algunas API más que pueden causar renderización dinámica,
00:02:04pero estas son las que encontramos con más frecuencia.
00:02:06En versiones anteriores de Next,
00:02:08una página se renderizaba como completamente estática o completamente dinámica.
00:02:13Una sola API dinámica en una página hará que toda la página opte por la renderización dinámica.
00:02:17Por ejemplo,
00:02:18hacer una simple verificación de autenticación para el valor de una cookie.
00:02:20Al utilizar componentes de servidor de React con `Suspense`,
00:02:23podemos transmitir contenido dinámico como un banner de bienvenida personalizado o recomendaciones a medida que estén listos y proporcionar solo fallbacks con `Suspense` mientras mostramos contenido estático como un boletín.
00:02:34Sin embargo,
00:02:34una vez que agregamos múltiples componentes asíncronos en una página dinámica,
00:02:38como un producto destacado,
00:02:40estos también se ejecutarían en el momento de la solicitud,
00:02:43aunque no dependieran de API dinámicas.
00:02:45Así que para evitar bloquear la carga inicial de la página,
00:02:48suspenderíamos y transmitiríamos esos componentes también,
00:02:51haciendo trabajo extra,
00:02:52creando esqueletos y preocupándonos por cosas como el cambio de diseño.
00:02:56Sin embargo,
00:02:57las páginas suelen ser una mezcla de contenido estático y dinámico.
00:03:01Por ejemplo,
00:03:01una aplicación de comercio electrónico que depende de la información del usuario mientras que aún contiene en su mayoría datos estáticos.
00:03:07Verse obligado a elegir entre ellos,
00:03:09entre estático o dinámico,
00:03:11causa mucho procesamiento redundante en el servidor sobre contenido que nunca o muy rara vez cambia y no es óptimo para el rendimiento.
00:03:19Así que para resolver este problema,
00:03:21en la Next.js Conf del año pasado,
00:03:23se anunció la directiva `use cache`.
00:03:26Y este año,
00:03:26como vimos en la presentación principal,
00:03:28está disponible en Next.js 16.
00:03:30Así que con `use cache`,
00:03:31las páginas ya no se verán obligadas a una renderización estática o dinámica.
00:03:36Pueden ser ambas.
00:03:37Y Next.js ya no tiene que adivinar qué es una página basándose en si accede a cosas como `params`.
00:03:43Todo es dinámico por defecto y `use cache` nos permite optar explícitamente por el almacenamiento en caché.
00:03:47`Use cache` permite el almacenamiento en caché componible.
00:03:51Podemos marcar una página,
00:03:53un componente de React o una función como cacheable.
00:03:55Aquí,
00:03:56en realidad podemos almacenar en caché el componente de productos destacados porque no necesita la solicitud y el procesamiento y no utiliza API dinámicas.
00:04:03Y estos segmentos de caché pueden ser pre-renderizados e incluidos como parte del shell estático con renderización parcial,
00:04:09lo que significa que los productos destacados ahora están disponibles al cargar la página y no necesitan ser transmitidos.
00:04:14Ahora que tenemos este importante conocimiento de fondo,
00:04:18hagamos una demostración.
00:04:19Una mejora de una base de código con problemas comunes frecuentemente encontrados en aplicaciones Next.js.
00:04:24Estos incluyen el `prop drilling` profundo,
00:04:25lo que dificulta mantener y refactorizar características,
00:04:28JavaScript redundante del lado del cliente y componentes grandes con múltiples responsabilidades,
00:04:31y la falta de renderización estática,
00:04:33lo que lleva a costos adicionales del servidor y un rendimiento degradado.
00:04:36Así que sí, empecemos.
00:04:37Y denme un segundo aquí.
00:04:50Muy bien, genial.
00:04:54Así que esta es una aplicación muy simple.
00:04:56Está inspirada en una plataforma de comercio electrónico.
00:04:59Y permítanme hacer una demostración inicial aquí.
00:05:01Así que puedo cargar esta página.
00:05:03Tengo contenido como este producto destacado.
00:05:06Tengo categorías destacadas, diferentes datos de productos.
00:05:09También está esta página 'Explorar todo' aquí donde puedo ver todos los productos de la plataforma y paginar entre ellos.
00:05:20Luego tenemos esta página 'Acerca de' aquí,
00:05:22que es simplemente estática.
00:05:24También puedo iniciar sesión como usuario.
00:05:27Y eso me conectará a mi usuario.
00:05:30Y también obtener contenido personalizado en mi panel de control aquí.
00:05:33Como por ejemplo,
00:05:34productos recomendados o estos descuentos personalizados aquí.
00:05:38Así que noten aquí, hay una mezcla bastante buena.
00:05:42Oh, también una página más que olvidé mostrarles.
00:05:45La página del producto, la más importante.
00:05:47También aquí,
00:05:48podemos ver información del producto y luego guardarla si queremos para nuestro usuario.
00:05:52Así que noten que hay una mezcla bastante buena de contenido estático y dinámico en esta aplicación debido a todas nuestras características dependientes del usuario.
00:05:59Echemos también un vistazo al código, que estaría aquí.
00:06:05Así que estoy usando el enrutador de aplicaciones aquí,
00:06:07por supuesto,
00:06:07en Next.js 16.
00:06:08Tengo todas mis diferentes páginas,
00:06:09como la página 'Acerca de',
00:06:11la página 'Todo',
00:06:12nuestra página de producto.
00:06:13También estoy usando `feature slicing` aquí para mantener limpia mi carpeta de la aplicación.
00:06:17Tengo diferentes componentes y consultas que se comunican con mi base de datos con Prisma.
00:06:23Así que sí, y a propósito ralenticé todo esto.
00:06:25Por eso tenemos esta etapa de carga tan larga,
00:06:28solo para que podamos ver más fácilmente lo que está sucediendo.
00:06:31Así que los problemas comunes en los que queríamos trabajar aquí y que realmente tenemos en esta aplicación eran el `prop drilling`,
00:06:37lo que dificulta mantener y refactorizar características,
00:06:39el exceso de JavaScript del lado del cliente y la falta de renderización estática que lleva a costos adicionales del servidor y un rendimiento degradado.
00:06:47Así que el objetivo de la demostración es básicamente mejorar esta aplicación con algunos patrones inteligentes sobre composición,
00:06:53almacenamiento en caché y arquitectura para solucionar esas características comunes y hacerla más rápida,
00:06:58más escalable y más fácil de mantener.
00:07:01Así que empecemos con eso.
00:07:02El primer problema que queremos solucionar en realidad está relacionado con el `prop drilling`.
00:07:05Y eso estaría aquí en la página.
00:07:10Noten aquí mismo,
00:07:11tengo esta variable `logged in` en la parte superior.
00:07:15Y pueden ver que la estoy pasando a un par de componentes.
00:07:17En realidad se ha pasado a través de múltiples niveles a este banner personal.
00:07:20Así que esto va a dificultar la reutilización de cosas aquí porque siempre tenemos esta dependencia de `logged in` para nuestro banner de bienvenida.
00:07:28Así que con los componentes de servidor,
00:07:30la mejor práctica sería realmente empujar la obtención de datos hacia los componentes que lo están usando y resolver promesas más profundamente en el árbol.
00:07:37Y para que esto se autentique,
00:07:39siempre y cuando esto esté usando `fetch` o algo como `React cache`,
00:07:42podemos duplicar múltiples llamadas de esto,
00:07:45y podemos reutilizarlo donde queramos dentro de nuestros componentes.
00:07:48Así que estaría totalmente bien reutilizarlo.
00:07:51Así que ahora podemos mover esto a la sección personalizada aquí.
00:07:54Y ya no vamos a necesitar esta prop.
00:07:57Y simplemente ponerlo directamente... ups... aquí.
00:08:01Y ya no vamos a necesitar pasar esto.
00:08:04Y como ahora estamos moviendo esta llamada asíncrona a la sección personalizada,
00:08:07ya no estamos bloqueando la página.
00:08:09Podemos seguir adelante y suspender esto con un simple `Suspense` aquí.
00:08:13Y no vamos a necesitar este `fallback`.
00:08:16En cuanto al banner de bienvenida,
00:08:19supongo que haremos lo mismo.
00:08:22Pero intentar obtener la variable o valor `logged in` aquí,
00:08:26no funciona,
00:08:27¿verdad?
00:08:27Porque este es un componente de cliente.
00:08:29Así que necesitamos resolver esto de una manera diferente.
00:08:30Y vamos a usar un patrón bastante inteligente aquí para resolver esto.
00:08:33En realidad vamos a ir al `layout` y envolver todo aquí con un proveedor de autenticación.
00:08:39Así que voy a poner esto alrededor de toda mi aplicación aquí y obtener esta variable `logged in` aquí.
00:08:45Y definitivamente no quiero bloquear todo mi `root layout`.
00:08:48Vamos a quitar el `await` aquí.
00:08:50Y simplemente pasar esto como una promesa a este proveedor de autenticación.
00:08:55Y esto puede simplemente contener esa promesa.
00:08:57Puede estar ahí esperando hasta que estemos listos para leerla.
00:09:01Así que ahora tenemos esto configurado.
00:09:03Eso significa que en realidad podemos seguir adelante y nos desharemos de esta prop,
00:09:08primero que nada.
00:09:09Y nos desharemos de este que se pasa al banner personal.
00:09:12Y nos desharemos del `prop drilling` también aquí o de la firma.
00:09:16Y ahora podemos usar este proveedor de autenticación para obtener este valor `logged in` localmente dentro del banner personal con `use auth` con ese proveedor que acabamos de crear.
00:09:26Y leerlo con `use`.
00:09:28Así que esto en realidad funcionará de una manera en la que necesitamos suspender esto mientras se resuelve.
00:09:33Así que ahora simplemente co-localicé esa pequeña obtención de datos dentro del banner personal.
00:09:37Y no tengo que pasar esas props.
00:09:40Y mientras esto se resuelve,
00:09:41vamos a suspender este también con un `fallback`.
00:09:44Y vamos a hacer un banner general aquí para evitar cualquier cambio acumulativo extraño.
00:09:51Y finalmente, también deshacernos de este.
00:09:53Así que ahora este banner de bienvenida es componible.
00:09:58Es reutilizable.
00:09:59No tenemos ninguna prop o dependencia extraña en la página de inicio.
00:10:02Y como podemos reutilizar esto tan fácilmente,
00:10:05vamos a añadirlo también a esta página del navegador aquí,
00:10:10que estará aquí.
00:10:11Y puedo simplemente usarlo aquí sin ninguna dependencia.
00:10:15Así que a través de estos patrones,
00:10:18podemos mantener una buena arquitectura de componentes utilizando `React cache`,
00:10:24`React use`,
00:10:25y hacer nuestros componentes más utilizables y componibles.
00:10:30Muy bien.
00:10:31Abordemos el siguiente desafío común,
00:10:33que sería el JavaScript excesivo del lado del cliente y los componentes grandes con múltiples responsabilidades.
00:10:40En realidad, eso también está en la página 'Todo' aquí.
00:10:43Y de nuevo,
00:10:43tendremos que trabajar en este banner de bienvenida.
00:10:46Actualmente es un componente de cliente.
00:10:48Y la razón por la que es un componente de cliente es porque tengo este estado de 'descartado' muy simple aquí.
00:10:53Puedo simplemente hacer clic aquí.
00:10:54Es una buena interacción de interfaz de usuario.
00:10:56Eso está bien.
00:10:57Lo que no está tan bien,
00:10:58sin embargo,
00:10:59es que debido a eso,
00:10:59convierto todo este componente en un componente del lado del cliente o un componente de cliente.
00:11:04E incluso uso `swr` para la obtención de datos del lado del cliente.
00:11:07Ahora tengo esta capa de API aquí.
00:11:08Ya no tengo seguridad de tipos en mis datos.
00:11:11Sí, esto no es necesario.
00:11:12Y también estamos rompiendo la separación de preocupaciones aquí porque estamos mezclando la lógica de la interfaz de usuario con los datos.
00:11:18Así que vamos a usar otro patrón inteligente para solucionar esto.
00:11:21Se llama el patrón `donut`.
00:11:23Básicamente,
00:11:23lo que voy a hacer es extraer esto en un `wrapper` del lado del cliente.
00:11:27Así que vamos a crear un nuevo componente aquí.
00:11:29Y llamémoslo `banner container`.
00:11:32Y esto va a contener nuestra lógica interactiva con la directiva `use client`.
00:11:37Podemos crear la firma.
00:11:38Podemos pegar todo lo que teníamos antes.
00:11:42Y en lugar de usar estos banners,
00:11:44voy a insertar una prop aquí,
00:11:46que serán los `children`.
00:11:48Por eso se llama el patrón `donut`.
00:11:50Simplemente estamos haciendo esta lógica de interfaz de usuario `wrapper` alrededor del contenido renderizado por el servidor,
00:11:54o podría ser contenido renderizado por el servidor.
00:11:56Y luego,
00:11:57como ya no tenemos esta dependencia del lado del cliente,
00:11:59podemos seguir adelante y eliminar el `use client`.
00:12:01Podemos usar nuestra función asíncrona `isAuth` aquí en su lugar.
00:12:06Podemos convertir esto en un componente de servidor asíncrono.
00:12:09Incluso podemos reemplazar la obtención de datos del lado del cliente con la obtención de datos del lado del servidor.
00:12:11Así que voy a obtener los datos de descuento directamente aquí.
00:12:16Datos de descuento.
00:12:18Y simplemente utilizar nuestro modelo mental regular como antes con seguridad de tipos.
00:12:24Y eso significa que también puedo eliminar esta capa de API con la que no quiero trabajar de todos modos.
00:12:29Finalmente,
00:12:29para el `isLoading`,
00:12:30podemos simplemente exportar un nuevo banner de bienvenida aquí con nuestro `banner container` con patrón `donut` que contiene contenido renderizado por el servidor.
00:12:38Y eso significa que ya no necesitamos este `isLoading`.
00:12:40Así que básicamente refactorizamos todo esto en un componente de servidor y extraemos un punto de lógica de interfaz de usuario.
00:12:46¿Pero qué es eso?
00:12:48Parece que tengo otro error.
00:12:51Así que esto es en realidad debido a `Motion`.
00:12:53Estoy usando `Motion`.
00:12:54Es una biblioteca de animación realmente genial,
00:12:57pero requiere la directiva `useClient`.
00:12:59Y de nuevo,
00:12:59no tenemos que hacer que esto sea `useClient` solo para la animación.
00:13:03Podemos crear,
00:13:04de nuevo,
00:13:04un `wrapper` con patrón `donut` y simplemente extraer `wrappers` para estas animaciones.
00:13:10Y eso significa que no tenemos que convertir nada aquí en el lado del cliente.
00:13:14Y probablemente me falta algo aquí abajo.
00:13:17Sí.
00:13:18Ahí vamos.
00:13:21Así que ahora todo aquí ha sido convertido a servidor.
00:13:23Tenemos la misma interacción.
00:13:24Todavía tenemos nuestra lógica interactiva aquí,
00:13:27pero ahora tenemos esta única forma de obtener datos.
00:13:29Y tenemos mucho menos JS del lado del cliente.
00:13:31En realidad,
00:13:32estoy usando este patrón `donut` yo misma para este `UI boundary helper`,
00:13:41que se ve así.
00:13:42¿Ven eso?
00:13:43Así que esto muestra, de nuevo, a qué me refiero, ¿verdad?
00:13:45Con el patrón `donut`,
00:13:46tenemos este componente de cliente alrededor de un componente de servidor.
00:13:49También marqué muchos de mis otros componentes con este `UI helper` aquí.
00:13:53También aquí, tengo más componentes de servidor.
00:13:56Vamos a mejorarlos también,
00:13:58ya que ya somos bastante buenos en esto.
00:14:01Están en el pie de página.
00:14:04Estas categorías...
00:14:04quiero decir,
00:14:05tengo este buen componente que obtiene sus propios datos..
00:14:08Y solo quería añadir esto de `showMore`,
00:14:11por si acaso se alarga mucho.
00:14:14Y con el patrón `donut`,
00:14:15puedo simplemente envolver un componente `showMore` aquí.
00:14:20Y esto contendrá mi lógica de interfaz de usuario.
00:14:23Y se ve así, ¿verdad?
00:14:27Bastante genial.
00:14:28Y esto ahora contiene la lógica del cliente,
00:14:31permitiéndonos usar el estado.
00:14:33Estamos usando el recuento de `children` y `to array` para cortar esto.
00:14:36Y lo genial aquí es que estos dos ahora son componentes completamente componibles y reutilizables que funcionan juntos así.
00:14:42Así que esta es realmente la belleza de estos patrones que estamos aprendiendo aquí.
00:14:45Puedes usar esto para cualquier cosa.
00:14:50También lo uso para este modal aquí.
00:14:52Sí,
00:14:52solo recuerden esto la próxima vez que estén considerando añadir cualquier tipo de lógica de cliente a sus componentes de servidor.
00:14:59OK, conocemos el patrón `donut`.
00:15:01Sabemos cómo utilizarlo para crear estos componentes componibles y evitar JavaScript del lado del cliente,
00:15:07así que podemos avanzar al problema final.
00:15:10Voy a cerrar esto de nuevo.
00:15:13Así que eso sería con la falta de estrategias de renderización estática,
00:15:18¿verdad?
00:15:18Mirando mi salida de compilación,
00:15:20en realidad tengo cada página como una página dinámica aquí.
00:15:24Así que eso significa que cada vez que cargo algo aquí,
00:15:27esto se va a ejecutar para cada usuario.
00:15:29Lo siento.
00:15:30Cada usuario que acceda a esto va a obtener este estado de carga.
00:15:33Va a estar desperdiciando costos de servidor,
00:15:35empeorando el rendimiento.
00:15:37Y eso significa también que algo dentro de mis páginas está causando renderización dinámica o forzando la renderización dinámica para todas mis páginas.
00:15:45En realidad, está dentro de mi `root layout`.
00:15:49No sé si han experimentado esto.
00:15:51Está aquí.
00:15:53En mi encabezado, tengo este perfil de usuario.
00:15:57Y esto,
00:15:57por supuesto,
00:15:58está usando cookies para obtener el usuario actual,
00:16:00y eso significa que todo lo demás también se renderiza dinámicamente.
00:16:02Porque de nuevo,
00:16:03las páginas podrían ser dinámicas o estáticas,
00:16:05¿verdad?
00:16:06Este es un problema bastante común y algo que se ha resuelto antes en versiones anteriores de Next,
00:16:11así que veamos qué podríamos hacer.
00:16:13Una cosa que podríamos hacer es crear un grupo de rutas y dividir nuestra aplicación en secciones estáticas y dinámicas,
00:16:20lo que me permitiría extraer mi página 'Acerca de'.
00:16:23Podría renderizar esto estáticamente.
00:16:25Está bien para algunas aplicaciones,
00:16:27pero en mi caso,
00:16:27la página importante es la página del producto,
00:16:30y esta sigue siendo dinámica,
00:16:31así que no es realmente útil.
00:16:33¿Qué tal esta estrategia?
00:16:35Así que aquí estoy creando este parámetro de contexto de solicitud codificando un cierto estado en mi URL,
00:16:41y luego puedo usar `generate static params` para generar todas las diferentes variantes de mis páginas.
00:16:46Eso,
00:16:47en realidad,
00:16:47combinado con la obtención de datos de usuario del lado del cliente,
00:16:51me permitiría obtener esto en caché en mi página de producto.
00:16:54Definitivamente un patrón viable.
00:16:55Es recomendado por el SDK de Vercel Flags,
00:16:58llamado el patrón `precompute`,
00:17:00creo.
00:17:00Pero esto es realmente complejo,
00:17:02y tengo múltiples formas de obtener datos.
00:17:04Y en realidad,
00:17:04no quiero reescribir toda mi aplicación en esto.
00:17:07¿Y si no tuviéramos que hacer ninguna de esas soluciones?
00:17:10¿Y si hubiera una forma más sencilla?
00:17:12Bueno, la hay.
00:17:14Volvamos a nuestra aplicación de nuevo.
00:17:17Así que en realidad podemos ir a la configuración de Next y simplemente habilitar los componentes de caché.
00:17:23Oh, genial.
00:17:25OK,
00:17:25y lo que esto hace,
00:17:26como saben por la presentación principal,
00:17:28en realidad hará que todas nuestras llamadas asíncronas opten por el tiempo de solicitud o dinámico.
00:17:34Y también nos dará errores cada vez que tengamos alguna llamada asíncrona no suspendida,
00:17:39y nos dará esta directiva `use cache` que podemos usar para almacenar en caché de forma granular una página,
00:17:46una función o un componente.
00:17:48Así que sí, vamos a utilizar esto.
00:17:51Podemos empezar con la página de inicio aquí.
00:17:55Echemos un vistazo.
00:17:56Así que de nuevo,
00:17:57tengo esta mezcla de contenido estático y dinámico.
00:17:59Tengo mi banner de bienvenida para mí,
00:18:01algo para ti también para mí.
00:18:03Echemos un vistazo a eso con este `UI helper` de nuevo.
00:18:06Así que por ejemplo,
00:18:07el banner se renderiza dinámicamente con esto de aquí.
00:18:10Mientras que marqué esto como renderización híbrida porque el héroe está obteniendo esta cosa asíncrona y va bastante lento.
00:18:18Pero no depende de ningún tipo de datos de usuario o API dinámicas.
00:18:21Así que eso significa que todo lo que se renderiza de forma híbrida aquí en realidad puede ser reutilizado en diferentes solicitudes y usuarios.
00:18:27Y podemos usar la directiva `use cache` en eso.
00:18:30Así que vamos a añadir la directiva `use cache` aquí y marcar esto como cacheado.
00:18:35Y eso me permitirá...
00:18:37cada vez que recargue esta página...
00:18:41no guardé esto..
00:18:43Ahí vamos.
00:18:44No recargará esta parte porque está en caché.
00:18:47Ahora es estático, ¿verdad?
00:18:49Y también hay otras API relacionadas como la etiqueta de caché para permitirme tipar esto o validar la entrada de caché específica de forma granular o definir mi período de revalidación.
00:19:01Pero para esta demostración,
00:19:03centrémonos solo en la directiva simple.
00:19:05Ahora que tengo esta directiva `use cache`,
00:19:07en realidad puedo eliminar mi límite de `Suspense` alrededor de este héroe.
00:19:10Y eso significa...
00:19:12bueno,
00:19:12lo que esto hará es que la renderización parcial puede incluir esto en el shell pre-renderizado estáticamente para que este héroe,
00:19:20en este caso,
00:19:21sea parte de mi salida de compilación..
00:19:23Hagamos lo mismo para todo lo demás en esta página que se pueda compartir.
00:19:28Por ejemplo, tengo estas categorías destacadas aquí.
00:19:31Vamos a hacer lo mismo allí.
00:19:33Y añadir la directiva `use cache` y marcar esto como cacheado.
00:19:37Así.
00:19:39Y podemos eliminar el límite de `Suspense`.
00:19:40Ya no vamos a necesitar esto.
00:19:43Lo mismo para los productos destacados.
00:19:44Vamos a añadir `use cache` y marcar esto como cacheado.
00:19:48Ups.
00:19:50Y luego eliminar el límite de `Suspense`.
00:19:52Así que noten cuánta complejidad soy capaz de eliminar aquí.
00:19:55No tengo que preocuparme por mis esqueletos,
00:19:57mi cambio de diseño acumulativo que estaba haciendo antes.
00:20:00Y la página ya no...
00:20:01o ya no tenemos esta limitación a nivel de página de estático versus dinámico..
00:20:07Así que ahora,
00:20:08cuando cargo esta página,
00:20:10verán que todo aquí está en caché excepto por este contenido verdaderamente específico del usuario.
00:20:16Correcto.
00:20:18Así que eso es bastante genial.
00:20:19Vamos a la página 'Explorar' y hagamos lo mismo allí.
00:20:24Sí.
00:20:25Ya marqué todos mis límites aquí para que puedan entender fácilmente lo que está sucediendo.
00:20:29Y quiero al menos almacenar en caché estas categorías.
00:20:33Parece que estoy recibiendo un error, sin embargo.
00:20:37Quizás reconozcan esto.
00:20:38Así que significa que tengo una ruta de bloqueo.
00:20:40Y no estoy usando el límite de `Suspense` cuando debería hacerlo.
00:20:43Al actualizar esto, es verdad, ¿eh?
00:20:46Esto es realmente lento.
00:20:47Y está causando problemas de rendimiento y una mala experiencia de usuario.
00:20:50Así que esto es genial.
00:20:51`Use cache` o los componentes de caché me están ayudando a identificar mis rutas de bloqueo.
00:20:55Veamos en realidad qué está pasando dentro de eso.
00:20:57Así que este es el problema, ¿verdad?
00:20:59Estoy obteniendo estas categorías de nivel superior y no tengo ningún límite de `Suspense` encima.
00:21:03Básicamente, tenemos que tomar una decisión.
00:21:05O añadimos un límite de `Suspense` encima o optamos por el almacenamiento en caché.
00:21:09Hagamos lo simple primero y simplemente añadamos un `loading.tsx` aquí.
00:21:12Y vamos a añadir una página de carga aquí,
00:21:16una bonita interfaz de usuario de esqueleto.
00:21:21Eso está bastante bien.
00:21:21Resolvió el error,
00:21:22pero no tengo nada útil sucediendo en esta página mientras espero.
00:21:25Ni siquiera puedo buscar.
00:21:27Así que con los componentes de caché, dinámico es como...
00:21:30o estático versus dinámico es como una escala..
00:21:33Y depende de nosotros decidir cuánto contenido estático queremos en nuestras páginas.
00:21:37Así que vamos a mover esta página más hacia lo estático y simplemente eliminemos este `loading.tsx` de nuevo.
00:21:43Y luego utilizar los patrones que estábamos aprendiendo antes para empujar esta obtención de datos al componente y co-localizarla con la interfaz de usuario.
00:21:50Así que movemos esto a mis filtros de categoría responsivos aquí.
00:21:54Tengo dos por el diseño responsivo.
00:21:57En realidad puedo seguir adelante y simplemente añadirlo aquí.
00:22:01Ups.
00:22:03E importar esto.
00:22:05Ya no necesito este `prompt`.
00:22:06En realidad, mi componente se está volviendo más componible.
00:22:09Y en lugar de suspenderlo,
00:22:11simplemente añadamos la directiva `use cache`.
00:22:14Y eso debería ser suficiente.
00:22:16Así que noten cómo me veo obligada a pensar más sobre dónde estoy resolviendo mis promesas y en realidad mejorando mi arquitectura de componentes a través de esto.
00:22:24No necesito suspender esto.
00:22:25Esto simplemente se incluirá en el shell estático aquí.
00:22:28La lista de productos, permítanme mantener esto fresco.
00:22:35Así que puedo recargar eso cada vez.
00:22:37Mientras que las categorías en la parte inferior,
00:22:39también quiero almacenar esto en caché.
00:22:41Así que vamos a ir al pie de página.
00:22:44Y como estoy usando el patrón `donut` aquí,
00:22:46esto en realidad puede ser almacenado en caché aunque esté dentro de esta parte de la interfaz de usuario que es interactiva.
00:22:54Así que esto está totalmente bien.
00:22:55Así que ese patrón no solo fue bueno para la composición,
00:22:57sino también para el almacenamiento en caché.
00:22:58Creo que tengo un error más allí.
00:23:03Veamos qué es eso.
00:23:04Todavía tengo este error.
00:23:08Esto es en realidad debido a estos `search params`.
00:23:10`Search params`, como sabemos, es una API dinámica.
00:23:12No puedo almacenar esto en caché.
00:23:13Pero puedo resolverlo más profundamente para revelar más de mi interfaz de usuario y hacerla estática.
00:23:18Así que vamos a mover esto hacia abajo,
00:23:20pasarlo como una promesa a la lista de productos.
00:23:24Haremos que esto sea tipado como una promesa aquí, así.
00:23:30Vamos a resolverlo dentro de la lista de productos,
00:23:33usar los parámetros de búsqueda resueltos aquí y aquí.
00:23:36Y como esto está suspendido aquí, el error desaparecerá.
00:23:40Así que al recargar esto,
00:23:42lo único que se recarga aquí es solo la parte que elegí específicamente para que fuera dinámica.
00:23:48Todo lo demás puede ser almacenado en caché.
00:23:49Y eso significa que puedo interactuar con mi banner o incluso buscar porque esa parte ya ha sido pre-renderizada.
00:23:57Muy bien,
00:23:57hagamos la página final aquí,
00:24:00que es la página del producto,
00:24:02que es la más difícil y la más importante.
00:24:05Está realmente mal ahora mismo.
00:24:08Esto es súper importante para una plataforma de comercio electrónico,
00:24:10aparentemente.
00:24:11Muy bien, vamos a arreglar ese también.
00:24:15Así que aquí tengo esta página de producto.
00:24:18Empecemos a almacenar en caché solo el contenido reutilizable aquí,
00:24:21por ejemplo,
00:24:22el producto en sí.
00:24:23Y simplemente añadir `use cache` aquí y marcar esto como cacheado.
00:24:27Eso debería estar bien.
00:24:28Eso significa que podemos eliminar el límite de `Suspense` aquí.
00:24:33Muy bien,
00:24:33y esto ya no se recarga en cada solicitud aquí,
00:24:37¿verdad?
00:24:38Para los detalles del producto, hagamos lo mismo.
00:24:40Vamos a añadir `use cache`.
00:24:41Vamos a marcarlo como cacheado y ver si eso también funciona.
00:24:47No lo hizo.
00:24:48En realidad, este es un error diferente.
00:24:50Me está diciendo que estoy intentando usar API dinámicas dentro de este segmento cacheado.
00:24:54Y eso es cierto.
00:24:54Estoy usando el botón 'Guardar Producto', ¿verdad?
00:24:56Eso me permitió hacer clic y alternar el estado guardado.
00:25:00¿Así que qué creen que podemos hacer con esto?
00:25:03Podemos usar el patrón `donut` de nuevo.
00:25:06En realidad,
00:25:06también podemos insertar segmentos dinámicos en segmentos de caché.
00:25:10Así que los estamos intercalando como antes, pero con caché.
00:25:12Así que esto es bastante genial.
00:25:14Vamos a añadir los `children` aquí así.
00:25:19Y esto eliminará el error.
00:25:21Y puedo simplemente envolver esto alrededor de este segmento dinámico de mi página aquí,
00:25:26eliminar el límite de `Suspense`,
00:25:28y añadir una interfaz de usuario de marcador muy pequeña para esa única pieza dinámica de la página.
00:25:34Y veamos cómo se ve eso ahora.
00:25:40Así que noten cómo casi toda la interfaz de usuario está disponible,
00:25:43pero tengo este pequeño fragmento que es dinámico,
00:25:46y eso está bien.
00:25:47Todo lo demás sigue ahí.
00:25:48Y dejemos las reseñas dinámicas porque podríamos mantenerlas frescas.
00:25:53Todavía hay un error más.
00:25:54Vamos a abordar eso rápidamente.
00:25:56De nuevo, estos son los `params`.
00:25:58Estoy recibiendo ayuda de que necesito tomar una decisión: o añadir un `loading fallback` o almacenar esto en caché.
00:26:04Vamos a usar `generate static params` en este caso.
00:26:07Depende un poco de tu caso de uso y de tu conjunto de datos.
00:26:10Pero para este caso,
00:26:10simplemente voy a añadir un par de páginas pre-renderizadas predefinidas y luego simplemente almacenar en caché el resto a medida que son generadas por los usuarios.
00:26:17Y esto eliminará mi error aquí.
00:26:20Así que creo que en realidad he terminado con mi refactorización.
00:26:22Vamos a echar un vistazo a la versión desplegada y ver cómo se ve.
00:26:26Así que acabo de desplegar esto en Vercel.
00:26:27Y recuerden,
00:26:29a propósito ralenticé muchas obtenciones de datos aquí.
00:26:35Y aún así,
00:26:36cuando cargo esta página inicialmente,
00:26:39todo ya está disponible.
00:26:40Lo único aquí son solo esos pocos segmentos dinámicos como los descuentos y el 'para ti'.
00:26:46Lo mismo con el 'explorar todo'.
00:26:47Toda la interfaz de usuario ya está disponible.
00:26:50Y para el producto en sí, simplemente se siente instantáneo.
00:26:54Y recuerden,
00:26:55de nuevo,
00:26:55que todos estos segmentos de caché se incluirán con el shell estático con renderización parcial.
00:27:00Y puede ser pre-obtenido usando la pre-obtención mejorada en el nuevo enrutador de cliente de Next 16.
00:27:05Así que eso significa que cada navegación simplemente...
00:27:08se siente tan rápida, ¿verdad?.
00:27:09Muy bien,
00:27:10para resumir,
00:27:11con los componentes de caché,
00:27:14ya no hay estático versus dinámico.
00:27:17Y no necesitamos evitar las API dinámicas o comprometer el contenido dinámico.
00:27:28Y podemos omitir estos hacks y soluciones complejas usando múltiples estrategias de obtención de datos solo para ese...
00:27:35este acierto de caché, como les mostré..
00:27:37Así que en Next.js moderno,
00:27:39dinámico versus estático es una escala.
00:27:40Y nosotros decidimos cuánto contenido estático queremos en nuestras aplicaciones.
00:27:43Y siempre y cuando sigamos ciertos patrones,
00:27:45podemos tener un modelo mental que es performante,
00:27:48componible y escalable por defecto.
00:27:50Así que volvamos a las diapositivas.
00:27:53Así que si no estaban ya impresionados por la velocidad de eso,
00:27:55esta es la puntuación de Lighthouse.
00:27:56Así que recopilé algunos datos de campo con Vercel Speed Insights.
00:28:00Así que tenemos una puntuación de 100 en todas las páginas más importantes: la página de inicio,
00:28:04la página del producto y la lista de productos,
00:28:06a pesar de que son altamente dinámicas.
00:28:08Así que vamos a resumir finalmente los patrones que garantizarán la escalabilidad y el rendimiento en las aplicaciones Next.js y nos permitirán aprovechar las últimas innovaciones y obtener puntuaciones como esta.
00:28:18Así que,
00:28:19en primer lugar,
00:28:19podemos refinar nuestra arquitectura resolviendo promesas profundamente en el árbol de componentes y obteniendo datos localmente dentro de los componentes usando `React Cache` para evitar trabajo duplicado.
00:28:28Podemos evitar el paso excesivo de props a los componentes de cliente usando proveedores de contexto combinados con `React Use`.
00:28:35Segundo,
00:28:35podemos componer componentes de cliente de servicio usando el patrón `donut` para reducir el JavaScript del lado del cliente,
00:28:40mantener una clara separación de preocupaciones y permitir la reutilización de componentes.
00:28:43Y este patrón nos permitirá además almacenar en caché nuestros componentes de servidor compuestos más tarde.
00:28:50Y finalmente,
00:28:50podemos almacenar en caché y pre-renderizar con `use cache` ya sea por página,
00:28:53componente o función para eliminar el procesamiento redundante,
00:28:56aumentar el rendimiento y el SEO,
00:28:57y dejar que la renderización parcial renderice estáticamente estos segmentos de la aplicación.
00:29:01Y si nuestro contenido es verdaderamente dinámico,
00:29:04podemos suspenderlo con `fallbacks` de carga apropiados.
00:29:07Y recuerden que todo esto está conectado.
00:29:09Así que cuanto mejor sea tu arquitectura,
00:29:10más fácil será componer,
00:29:11y más fácil será almacenar en caché y pre-renderizar con los mejores resultados.
00:29:15Por ejemplo,
00:29:15resolver API dinámicas profundamente en el árbol te permitirá crear un shell estático pre-renderizado parcialmente más grande.
00:29:22Y con eso,
00:29:22este es el repositorio de la versión completada de la aplicación.
00:29:25Hay tantas cosas que ni siquiera mostré allí que pueden revisar.
00:29:29Y pueden escanear el código QR para encontrar mis redes sociales allí junto con el repositorio si no quieren tomar una foto y escribirlo ustedes mismos.
00:29:36Así que sí, eso es todo por mi parte.
00:29:37Gracias Next.js Conf por tenerme aquí.
00:29:39[MÚSICA]

Key Takeaway

Next.js 16, con la directiva `use cache` y patrones de composición avanzados como el 'Donut Pattern', permite a los desarrolladores crear aplicaciones altamente escalables y de alto rendimiento que combinan contenido estático y dinámico de manera eficiente, optimizando la experiencia del usuario y los costos del servidor.

Highlights

Next.js 16 introduce la directiva `use cache` para un almacenamiento en caché componible y granular, permitiendo páginas híbridas estáticas y dinámicas.

Patrones como el 'Donut Pattern' y la resolución profunda de promesas mejoran la composición de componentes y reducen el JavaScript del lado del cliente.

La refactorización de la arquitectura de componentes y el uso de `React cache` y `React use` eliminan el 'prop drilling' y la duplicación de datos.

`use cache` permite pre-renderizar segmentos estáticos de la aplicación, mejorando el rendimiento, el SEO y la experiencia del usuario mediante renderización parcial.

Se demuestran soluciones prácticas para problemas comunes como el 'prop drilling', el exceso de JavaScript del lado del cliente y la falta de renderización estática.

La aplicación optimizada logra puntuaciones de Lighthouse de 100 en páginas clave, a pesar de su naturaleza altamente dinámica, gracias a la implementación de estos patrones.

La clave es considerar la renderización estática y dinámica como una escala, decidiendo cuánto contenido estático se desea en cada parte de la aplicación.

Timeline

Introducción a Next.js Moderno y Conceptos Clave

Aurora, una desarrolladora web de Noruega, da la bienvenida y presenta el tema de la charla: patrones de composición, almacenamiento en caché y arquitectura en Next.js moderno. Su objetivo es enseñar cómo garantizar la escalabilidad y el rendimiento en las aplicaciones. Menciona su experiencia activa con el enrutador de aplicaciones de Next.js en su proyecto de consultoría actual. Esta introducción establece el contexto y la importancia de los temas técnicos que se abordarán a lo largo de la presentación.

Renderización Estática vs. Dinámica en Next.js

Se explican los conceptos fundamentales de renderización estática y dinámica, ambos presentes en el enrutador de aplicaciones de Next.js. La renderización estática permite construir sitios web más rápidos, ya que el contenido pre-renderizado puede ser almacenado en caché y distribuido globalmente, reduciendo la carga del servidor y mejorando el SEO. Por otro lado, la renderización dinámica es esencial para mostrar datos en tiempo real, contenido actualizado frecuentemente y servir contenido personalizado, como paneles de control de usuario. Se utilizan ejemplos como el sitio web de Next.js Conf para estático y el panel de control de Vercel para dinámico, ilustrando cuándo usar cada enfoque.

APIs que Forzan la Renderización Dinámica

La ponente detalla las APIs específicas que pueden hacer que una página se renderice dinámicamente en Next.js. Esto incluye el uso de las props `params` y `search params` (aunque `params` puede combinarse con `static params` para pre-renderizar), la lectura de cookies y encabezados de las solicitudes entrantes, y el uso de `fetch` con la configuración de caché `no store`. Se advierte que intentar almacenar en caché o pre-renderizar algo usando encabezados o cookies generará errores durante la compilación, ya que esa información no se puede conocer de antemano. Estas APIs son las que se encuentran con mayor frecuencia y fuerzan el comportamiento dinámico.

Limitaciones Anteriores y la Necesidad de `use cache`

En versiones anteriores de Next.js, una página se renderizaba como completamente estática o completamente dinámica, lo que significaba que una sola API dinámica en una página forzaba toda la página a optar por la renderización dinámica. Esto resultaba en un procesamiento redundante en el servidor para contenido que nunca o muy rara vez cambia, lo cual no era óptimo para el rendimiento. Aunque los componentes de servidor de React con `Suspense` permitían transmitir contenido dinámico, los componentes asíncronos no dependientes de APIs dinámicas también se ejecutaban en tiempo de solicitud, generando trabajo extra y problemas de diseño. La necesidad de una solución más granular para páginas con contenido mixto era evidente.

Introducción de la Directiva `use cache` en Next.js 16

Para resolver el problema de la elección binaria entre renderización estática y dinámica, se anuncia la directiva `use cache`, disponible en Next.js 16. Con `use cache`, las páginas ya no están obligadas a ser estáticas o dinámicas; pueden ser ambas, y Next.js ya no tiene que adivinar el tipo de renderización basándose en el acceso a APIs dinámicas. Por defecto, todo es dinámico, y `use cache` permite optar explícitamente por el almacenamiento en caché de forma componible. Esto significa que se pueden marcar páginas, componentes de React o funciones como cacheables, permitiendo que segmentos de caché sean pre-renderizados e incluidos en el shell estático con renderización parcial, eliminando la necesidad de transmisión para contenido estático.

Demostración: Problemas Comunes en Aplicaciones Next.js

Se inicia una demostración práctica para mejorar una base de código con problemas comunes en Next.js, como el 'prop drilling' profundo, JavaScript redundante del lado del cliente y la falta de renderización estática. La aplicación de ejemplo es una plataforma de comercio electrónico simple con páginas como inicio, explorar, acerca de, y productos, que mezclan contenido estático y dinámico (ej. panel de control personalizado). Se muestra cómo la aplicación actual sufre de largos tiempos de carga debido a la ralentización intencional para ilustrar los problemas de rendimiento. El objetivo es refactorizar la aplicación para hacerla más rápida, escalable y fácil de mantener, abordando cada problema sistemáticamente.

Solución al 'Prop Drilling' con Componentes de Servidor

El primer problema abordado es el 'prop drilling' excesivo, donde una variable como `logged in` se pasa a través de múltiples niveles de componentes, dificultando la reutilización. La solución propuesta es empujar la obtención de datos hacia los componentes que los usan y resolver promesas más profundamente en el árbol de componentes, utilizando `React cache` o `fetch` para evitar duplicación de llamadas. Para el banner de bienvenida, que es un componente de cliente, se introduce un proveedor de autenticación en el `layout` raíz que pasa la promesa de autenticación. Esto permite que el banner acceda al estado `logged in` localmente con `use auth` y `React use`, eliminando la dependencia de props y mejorando la componibilidad y reutilización del componente.

El 'Donut Pattern' para Reducir JavaScript del Lado del Cliente

Se aborda el problema del JavaScript excesivo del lado del cliente y los componentes grandes con múltiples responsabilidades. El 'Donut Pattern' se introduce como una solución, extrayendo la lógica interactiva del lado del cliente en un componente `wrapper` (`banner container`) que recibe `children` renderizados por el servidor. Esto permite que el contenido principal sea un componente de servidor asíncrono, obteniendo datos directamente del lado del servidor con seguridad de tipos y eliminando capas de API innecesarias. El patrón también se aplica para envolver animaciones de bibliotecas como `Motion`, manteniendo el componente principal como servidor y reduciendo significativamente el JavaScript del lado del cliente, mejorando la separación de preocupaciones y la reutilización.

Estrategias para la Renderización Estática: Desafíos y Soluciones Antiguas

Se discute la falta de estrategias de renderización estática, donde todas las páginas se renderizan dinámicamente, resultando en costos de servidor y rendimiento degradado. Se explica que esto a menudo se debe a APIs dinámicas en el `root layout`, como la obtención del perfil de usuario a través de cookies. Se mencionan soluciones previas como la creación de grupos de rutas para dividir la aplicación en secciones estáticas y dinámicas, o el uso del patrón 'precompute' con `generate static params` y obtención de datos de usuario del lado del cliente. Sin embargo, estas soluciones se describen como complejas, difíciles de mantener y no siempre adecuadas para todas las aplicaciones, lo que subraya la necesidad de un enfoque más sencillo.

Habilitando `use cache` y Caching Granular

La solución definitiva para la renderización estática es habilitar los componentes de caché en la configuración de Next.js, lo que hace que todas las llamadas asíncronas opten por el tiempo de solicitud dinámico por defecto. Esta configuración también ayuda a identificar llamadas asíncronas no suspendidas, forzando al desarrollador a tomar decisiones de renderización. La directiva `use cache` permite almacenar en caché de forma granular una página, función o componente. Se demuestra cómo añadir `use cache` a componentes como el héroe, categorías destacadas y productos destacados en la página de inicio, eliminando la necesidad de límites de `Suspense` y permitiendo que estos segmentos se incluyan en el shell estático pre-renderizado, mejorando la carga inicial.

Aplicando `use cache` en la Página 'Explorar Todo'

Se continúa la refactorización en la página 'Explorar Todo', donde se intenta almacenar en caché las categorías. Un error de 'ruta de bloqueo' revela la necesidad de un límite de `Suspense` o de optar por el almacenamiento en caché. En lugar de un simple `loading.tsx`, se opta por mover la obtención de datos de las categorías al componente de filtros de categoría responsivos y aplicar `use cache` allí, mejorando la arquitectura de componentes. Para los `search params`, que son dinámicos y no pueden ser cacheados, se resuelven más profundamente en la lista de productos y se suspenden, permitiendo que el resto de la interfaz de usuario sea estática e interactiva. Esto demuestra cómo `use cache` ayuda a identificar y resolver cuellos de botella de rendimiento.

Optimización de la Página de Producto con `use cache` y 'Donut Pattern'

La página de producto, considerada la más difícil y crucial para un e-commerce, se optimiza aplicando `use cache` al producto y sus detalles. Un error al intentar almacenar en caché el botón 'Guardar Producto' (que usa APIs dinámicas) se resuelve aplicando nuevamente el 'Donut Pattern', insertando un segmento dinámico dentro del componente cacheado. Esto permite que la mayor parte de la interfaz de usuario sea estática, con solo un pequeño fragmento dinámico. Para los `params` de la página de producto, se utiliza `generate static params` para predefinir algunas páginas pre-renderizadas y almacenar en caché el resto a medida que son generadas por los usuarios, eliminando el error y mejorando el rendimiento general de la página.

Resultados de la Demostración y Beneficios de los Patrones

Se muestra la versión desplegada de la aplicación refactorizada en Vercel, destacando la velocidad y la disponibilidad instantánea de la interfaz de usuario, incluso con la ralentización intencional de las obtenciones de datos. Solo los segmentos verdaderamente dinámicos, como descuentos y recomendaciones personalizadas, se cargan de forma asíncrona. Se enfatiza que los segmentos de caché se incluyen en el shell estático con renderización parcial y pueden ser pre-obtenidos por el nuevo enrutador de cliente de Next 16, resultando en navegaciones instantáneas. La aplicación logra puntuaciones de Lighthouse de 100 en páginas clave, a pesar de su naturaleza dinámica, demostrando el éxito de los patrones implementados.

Conclusión y Resumen de Patrones Clave

La charla concluye resumiendo los patrones clave para garantizar la escalabilidad y el rendimiento en Next.js moderno. Estos incluyen refinar la arquitectura resolviendo promesas profundamente y obteniendo datos localmente con `React Cache`, evitar el 'prop drilling' con proveedores de contexto y `React Use`, componer componentes de cliente de servicio con el 'Donut Pattern' para reducir JavaScript y permitir el almacenamiento en caché, y finalmente, usar `use cache` para un almacenamiento en caché granular y pre-renderización con renderización parcial. Se subraya la interconexión de estos patrones: una mejor arquitectura facilita la composición y el almacenamiento en caché, llevando a resultados óptimos y un shell estático más grande. Se proporciona un repositorio de la aplicación completada para referencia.

Community Posts

View all posts