Una guía completa para la regeneración estática incremental (ISR) con Next.js

Publicado: 2022-03-10
Resumen rápido ↬ La regeneración estática incremental (ISR) es una nueva evolución de Jamstack, que le permite actualizar el contenido estático al instante sin necesidad de una reconstrucción completa de su sitio. El enfoque híbrido de Next.js le permite usar ISR para comercio electrónico, páginas de marketing, publicaciones de blog, medios respaldados por anuncios y más.

Hace un año, Next.js 9.3 lanzó soporte para generación de sitios estáticos (SSG), convirtiéndolo en el primer marco híbrido. Había sido un usuario feliz de Next.js durante unos años en este punto, pero esta versión convirtió a Next.js en mi nueva solución predeterminada. Después de trabajar extensamente con Next.js, me uní a Vercel para ayudar a empresas como Tripadvisor y Washington Post a adoptar y escalar Next.js.

En este artículo, me gustaría explorar una nueva evolución de Jamstack: Regeneración estática incremental (ISR) . A continuación, encontrará una guía de ISR, que incluye casos de uso, demostraciones y compensaciones.

El problema con la generación de sitios estáticos

La idea detrás de Jamstack es atractiva: páginas estáticas renderizadas previamente que pueden enviarse a un CDN y estar disponibles globalmente en segundos. El contenido estático es rápido, resistente al tiempo de inactividad y los rastreadores lo indexan inmediatamente. Pero hay algunos problemas.

Si ha adoptado la arquitectura Jamstack mientras creaba un sitio estático a gran escala, es posible que tenga que esperar horas para que se construya su sitio. Si duplica el número de páginas, el tiempo de construcción también se duplica. Consideremos Target.com. ¿Es posible generar estáticamente millones de productos con cada implementación?

Gráfico de tiempo de construcción
El problema con la generación de sitios estáticos: debido a que los tiempos de construcción se escalan linealmente con la cantidad de páginas, es posible que se quede atrapado esperando horas para que se construya su sitio. (Vista previa grande)

Incluso si cada página se generara de forma estática en un tiempo poco realista de 1 ms, aún llevaría horas reconstruir todo el sitio . Para aplicaciones web grandes, elegir la generación completa de sitios estáticos no es un buen comienzo. Los equipos a gran escala necesitan una solución híbrida más flexible y personalizada.

Sistemas de gestión de contenido (CMS)

Para muchos equipos, el contenido de su sitio está desvinculado del código. El uso de un CMS sin cabeza permite a los editores de contenido publicar cambios sin involucrar a un desarrollador. Sin embargo, con los sitios estáticos tradicionales, este proceso puede ser lento.

Considere una tienda de comercio electrónico con 100.000 productos. Los precios de los productos cambian con frecuencia. Cuando un editor de contenido cambia el precio de los auriculares de $100 a $75 como parte de una promoción, su CMS usa un webhook para reconstruir todo el sitio. No es factible esperar horas a que se refleje el nuevo precio.

Las compilaciones largas con cálculos innecesarios también pueden incurrir en gastos adicionales. Idealmente, su aplicación es lo suficientemente inteligente como para comprender qué productos cambiaron y actualizar gradualmente esas páginas sin necesidad de una reconstrucción completa .

¡Más después del salto! Continúe leyendo a continuación ↓

Regeneración estática incremental (ISR)

Next.js le permite crear o actualizar páginas estáticas después de haber creado su sitio. La regeneración estática incremental (ISR) permite a los desarrolladores y editores de contenido usar la generación estática por página, sin necesidad de reconstruir todo el sitio . Con ISR, puede conservar los beneficios de la estática mientras escala a millones de páginas.

Las páginas estáticas se pueden generar en tiempo de ejecución (bajo demanda) en lugar de en tiempo de compilación con ISR. Al usar análisis, pruebas A/B u otras métricas, está equipado con la flexibilidad para hacer su propia compensación en los tiempos de construcción.

Considere la tienda de comercio electrónico de antes con 100,000 productos. Con un tiempo realista de 50 ms para generar estáticamente cada página de producto, esto llevaría casi 2 horas sin ISR . Con ISR, podemos elegir entre:

  • Construcciones más rápidas
    Genere los 1000 productos más populares en tiempo de compilación. Las solicitudes realizadas a otros productos se perderán en la memoria caché y se generarán estáticamente bajo demanda: compilaciones de 1 minuto.
  • Tasa de aciertos de caché más alta
    Genere 10 000 productos en tiempo de compilación, lo que garantiza que se almacenen en caché más productos antes de la solicitud de un usuario: compilaciones de 8 minutos.
Una ilustración que muestra Jamstack a la izquierda y Regeneración estática incremental a la derecha
La ventaja de ISR: tiene la flexibilidad de elegir qué páginas se generan en la construcción o bajo demanda. Elija entre (A) compilaciones más rápidas o (B) más en caché. (Vista previa grande)

Veamos un ejemplo de ISR para una página de producto de comercio electrónico.

Empezando

Recuperacion de datos

Si nunca antes ha usado Next.js, le recomiendo leer Primeros pasos con Next.js para comprender los conceptos básicos. ISR usa la misma API de Next.js para generar páginas estáticas: getStaticProps . Al especificar revalidate: 60 , le informamos a Next.js que use ISR para esta página.

Un diagrama del flujo de solicitud para la regeneración estática incremental
Un diagrama del flujo de solicitud para la regeneración estática incremental. (Vista previa grande)
  1. Next.js puede definir un tiempo de revalidación por página. Pongámoslo en 60 segundos.
  2. La solicitud inicial a la página del producto mostrará la página en caché con el precio original.
  3. Los datos del producto se actualizan en el CMS.
  4. Cualquier solicitud a la página después de la solicitud inicial y antes de 60 segundos se almacena en caché y es instantánea.
  5. Después de la ventana de 60 segundos, la siguiente solicitud aún mostrará la página almacenada en caché (obsoleta). Next.js desencadena una regeneración de la página en segundo plano .
  6. Una vez que la página se haya generado correctamente, Next.js invalidará el caché y mostrará la página del producto actualizada. Si la regeneración de fondo falla, la página anterior permanece inalterada.
 // pages/products/[id].js export async function getStaticProps({ params }) { return { props: { product: await getProductFromDatabase(params.id) }, revalidate: 60 } }

Generación de caminos

Next.js define qué productos generar en el momento de la compilación y cuáles a pedido. Generemos solo los 1000 productos más populares en el momento de la compilación proporcionando a getStaticPaths una lista de los 1000 ID de productos principales.

Necesitamos configurar cómo Next.js "retrocederá" cuando solicite cualquiera de los otros productos después de la compilación inicial. Hay dos opciones para elegir: blocking y true .

  • fallback: blocking (preferido)
    Cuando se realiza una solicitud a una página que no se ha generado, Next.js representará la página en el servidor en la primera solicitud. Las solicitudes futuras servirán el archivo estático desde el caché.
  • fallback: true
    Cuando se realiza una solicitud a una página que no se ha generado, Next.js entregará inmediatamente una página estática con un estado de carga en la primera solicitud. Cuando los datos terminen de cargarse, la página se volverá a representar con los nuevos datos y se almacenará en caché. Las solicitudes futuras servirán el archivo estático desde el caché.
 // pages/products/[id].js export async function getStaticPaths() { const products = await getTop1000Products() const paths = products.map((product) => ({ params: { id: product.id } })) return { paths, fallback: 'blocking' } }

compensaciones

Next.js se enfoca ante todo en el usuario final. La “mejor solución” es relativa y varía según la industria, la audiencia y la naturaleza de la aplicación. Al permitir que los desarrolladores cambien de solución sin salirse de los límites del marco, Next.js le permite elegir la herramienta adecuada para el proyecto.

Representación del lado del servidor

ISR no siempre es la solución correcta. Por ejemplo, la fuente de noticias de Facebook no puede mostrar contenido obsoleto. En este caso, querrá usar SSR y, potencialmente, sus propios encabezados cache-control con claves sustitutas para invalidar el contenido. Dado que Next.js es un marco híbrido, puede hacer esa compensación usted mismo y permanecer dentro del marco.

 // You can cache SSR pages at the edge using Next.js // inside both getServerSideProps and API Routes res.setHeader('Cache-Control', 's-maxage=60, stale-while-revalidate');

SSR y el almacenamiento en caché perimetral son similares a ISR (especialmente si se usan encabezados de almacenamiento en caché stale-while-revalidate ) y la principal diferencia es la primera solicitud. Con ISR, la primera solicitud puede garantizarse estática si se procesa previamente. Incluso si su base de datos deja de funcionar, o si hay un problema de comunicación con una API, sus usuarios seguirán viendo la página estática correctamente servida. Sin embargo, SSR le permitirá personalizar su página según la solicitud entrante.

Nota : el uso de SSR sin almacenamiento en caché puede provocar un rendimiento deficiente. Cada milisegundo es importante cuando se impide que el usuario vea su sitio, y esto puede tener un efecto dramático en su TTFB (Tiempo hasta el primer byte).

Generación de sitios estáticos

ISR no siempre tiene sentido para sitios web pequeños. Si su período de revalidación es mayor que el tiempo que lleva reconstruir todo su sitio, también podría usar la generación tradicional de sitios estáticos.

Representación del lado del cliente

Si usa React sin Next.js, está usando la representación del lado del cliente. Su aplicación presenta un estado de carga, seguido de una solicitud de datos dentro de JavaScript en el lado del cliente (por ejemplo useEffect ). Si bien esto aumenta sus opciones de hospedaje (ya que no es necesario un servidor), existen ventajas y desventajas.

La falta de contenido renderizado previamente desde el HTML inicial conduce a una optimización de motores de búsqueda (SEO) más lenta y menos dinámica. Tampoco es posible usar CSR con JavaScript deshabilitado.

Opciones de respaldo de ISR

Si sus datos se pueden recuperar rápidamente, considere usar fallback: blocking . Entonces, no necesita considerar el estado de carga y su página siempre mostrará el mismo resultado (independientemente de si está en caché o no). Si la obtención de datos es lenta, fallback: true le permite mostrar inmediatamente un estado de carga al usuario.

ISR: ¡No solo almacenamiento en caché!

Si bien he explicado ISR a través del contexto de un caché, está diseñado para conservar las páginas generadas entre implementaciones. Esto significa que puede retroceder instantáneamente y no perder las páginas generadas anteriormente.

Cada implementación puede tener una clave de ID, que Next.js usa para conservar las páginas generadas estáticamente. Cuando retrocede, puede actualizar la clave para que apunte a la implementación anterior, lo que permite implementaciones atómicas. Esto significa que puede visitar sus implementaciones inmutables anteriores y funcionarán según lo previsto.

  • Aquí hay un ejemplo de reversión de código con ISR:
  • Presiona el código y obtiene un ID de implementación 123.
  • Su página contiene un error tipográfico "Smshng Magazine".
  • Actualizas la página en el CMS. No es necesario volver a implementar.
  • Una vez que su página muestra "Smashing Magazine", se conserva en el almacenamiento.
  • Empuja un código incorrecto e implementa ID 345.
  • Vuelve al ID de implementación 123.
  • Todavía ves "Smashing Magazine".

Las reversiones y las páginas estáticas persistentes están fuera del alcance de Next.js y dependen de su proveedor de alojamiento. Tenga en cuenta que ISR difiere de la representación del servidor con encabezados Cache-Control porque, por diseño, los cachés caducan. No se comparten entre regiones y se eliminarán cuando se reviertan.

Ejemplos de regeneración estática incremental

La regeneración estática incremental funciona bien para el comercio electrónico, las páginas de marketing, las publicaciones de blog, los medios respaldados por anuncios y más.

  • Demostración de comercio electrónico
    Next.js Commerce es un kit de inicio todo en uno para sitios de comercio electrónico de alto rendimiento.
  • Demostración de reacciones de GitHub
    Reaccione al problema original de GitHub y observe cómo ISR actualiza la página de inicio generada estáticamente.
  • Demostración de tweets estáticos
    Este proyecto se implementa en 30 segundos, pero puede generar estáticamente 500 millones de tweets bajo demanda usando ISR.

Aprenda Next.js hoy

Los desarrolladores y los equipos grandes están eligiendo Next.js por su enfoque híbrido y su capacidad para generar páginas según demanda de forma incremental. Con ISR, obtiene los beneficios de la estática con la flexibilidad de la representación del servidor. ISR funciona de forma inmediata utilizando el next start .

Next.js ha sido diseñado para una adopción gradual. Con Next.js, puede continuar usando su código existente y agregar tanto (o tan poco) React como necesite. Al comenzar poco a poco y agregar más páginas de manera incremental, puede evitar que descarrile el trabajo de las funciones al evitar una reescritura completa. Obtenga más información sobre Next.js, ¡y feliz codificación para todos!

Otras lecturas

  • Primeros pasos con Next.js
  • Comparación de métodos de estilo en Next.js
  • Cómo construir un servidor GraphQL usando rutas API Next.js