Desglosando compilaciones voluminosas con Netlify y Next.js

 

 

 


Índice
  1. Construya una vez, actualice cuando sea necesario
  2. Constructores bajo demanda
  3. Crear un constructor bajo demanda
  4. Next.js en Netlify
  5. Constructores bajo demanda con Next.js
  6. Definición de rutas prerenderizadas
  7. Tiempos de construcción
  8. El futuro: renderizado persistente distribuido
  9. Conclusión
  10. Referencias

Static Generation es excelente para el rendimiento, hasta que la aplicación se vuelve demasiado grande y los tiempos de compilación se disparan. Hoy veremos cómo los nuevos On-Demand Builders de Netlify pueden solucionar este problema. Además, lo combinamos con la regeneración estática incremental de Next.js para brindar la mejor experiencia de usuario y desarrollador. Y, por supuesto, ¡compare esos resultados!

 

Este artículo ha sido apoyado amablemente por nuestros queridos amigos de Netlify , quienes son un grupo diverso de talentos increíbles de todo el mundo y ofrecen una plataforma para desarrolladores web que multiplica la productividad. ¡Gracias!

Uno de los mayores problemas de trabajar con sitios web generados estáticamente son las compilaciones cada vez más lentas a medida que crece la aplicación. Este es un problema inevitable al que se enfrenta cualquier pila en algún momento y puede ocurrir desde diferentes puntos dependiendo del tipo de producto con el que esté trabajando.

Por ejemplo, si su aplicación tiene varias páginas (vistas, rutas) al generar el artefacto de implementación, cada una de esas rutas se convierte en un archivo. Luego, una vez que haya llegado a miles, comenzará a preguntarse cuándo podrá implementarlo sin necesidad de planificar con anticipación. Este escenario es común en plataformas de comercio electrónico o blogs, que ya constituyen una gran parte de la web, pero no toda. Sin embargo, las rutas no son el único posible cuello de botella.

Una aplicación con muchos recursos también llegará eventualmente a este punto de inflexión. Muchos generadores estáticos llevan a cabo la optimización de activos para garantizar la mejor experiencia de usuario. Sin optimizaciones de compilación (compilaciones incrementales, almacenamiento en caché, llegaremos a ellas pronto), esto eventualmente también se volverá inmanejable; piense en revisar todas las imágenes en un sitio web: cambiar el tamaño, eliminar y/o crear nuevos archivos una y otra vez. Y una vez hecho todo esto: recuerde que Jamstack sirve nuestras aplicaciones desde los límites de la red de entrega de contenido . Por lo tanto, todavía necesitamos mover cosas desde el servidor en el que fueron compiladas a los bordes de la red.

 

Arquitectura de servicios generales de Jamstack ( vista previa grande )

Además de todo eso, también hay otro hecho: los datos suelen ser dinámicos, lo que significa que cuando creamos nuestra aplicación y la implementamos, puede tardar unos segundos, unos minutos o incluso una hora. Mientras tanto, el mundo sigue girando y si buscamos datos de otro lugar, nuestra aplicación seguramente quedará obsoleta. ¡Inaceptable! ¡Construya nuevamente para actualizar!

Construya una vez, actualice cuando sea necesario

Resolver Bulky Builds ha sido una prioridad para básicamente todas las plataformas, marcos o servicios de Jamstack durante un tiempo. Muchas soluciones giran en torno a compilaciones incrementales. En la práctica, esto significa que las compilaciones serán tan voluminosas como las diferencias que tengan con la implementación actual.

Sin embargo , definir un algoritmo de diferenciación no es una tarea fácil. Para que el usuario final realmente se beneficie de esta mejora, se deben considerar estrategias de invalidación de caché. En pocas palabras: no queremos invalidar el caché de una página o un activo que no ha cambiado.

A Next.js se le ocurrió la regeneración estática incremental ( ISR ). En esencia, es una forma de declarar para cada ruta con qué frecuencia queremos que se reconstruya. En el fondo, simplifica gran parte del trabajo del lado del servidor. Porque cada ruta ( dinámica o no) se reconstruirá a sí misma en un período de tiempo específico, y encaja perfectamente en el axioma de Jamstack de invalidar el caché en cada compilación. Piense en ello como el max-ageencabezado, pero para las rutas en su aplicación Next.js.

Para iniciar su aplicación, ISR está a solo una propiedad de configuración de distancia. En su componente de ruta (dentro del /pagesdirectorio), vaya a su getStaticPropsmétodo y agregue la revalidateclave al objeto de retorno:

export async function getStaticProps() { const { limit, count, pokemons } = await fetchPokemonList() return { props: { limit, count, pokemons, }, revalidate: 3600 // seconds }}

El fragmento anterior asegurará que mi página se reconstruya cada hora y busque más Pokémon para mostrar.

Todavía recibimos compilaciones masivas de vez en cuando (cuando publicamos una nueva implementación). Pero esto nos permite desacoplar el contenido del código, al mover el contenido a un Sistema de Gestión de Contenidos (CMS) podemos actualizar la información en unos segundos, sin importar el tamaño de nuestra aplicación. ¡Adiós a los webhooks por errores tipográficos de actualización!

Constructores bajo demanda

Netlify lanzó recientemente On-Demand Builders , que es su enfoque para admitir ISR para Next.js, pero también funciona en marcos como Eleventy y Nuxt. En la sesión anterior, establecimos que ISR fue un gran paso hacia tiempos de construcción más cortos y abordó una parte importante de los casos de uso. Sin embargo, las advertencias estaban ahí:

 

  1. Se basa completamente en una implementación continua.
    La etapa incremental ocurre sólo después de la implementación y para los datos. No es posible enviar el código de forma incremental
  2. Las compilaciones incrementales son producto del tiempo.
    La caché se invalida cada cierto tiempo. Por lo tanto, pueden ocurrir compilaciones innecesarias o las actualizaciones necesarias pueden demorar más dependiendo del período de revalidación establecido en el código.

La nueva infraestructura de implementación de Netlify permite a los desarrolladores crear lógica para determinar qué partes de su aplicación se construirán durante la implementación y qué partes se aplazarán (y cómo se aplazarán).

  • Crítico
    No es necesaria ninguna acción. Todo lo que implementes se basará en push .
  • Diferido
    Una parte específica de la aplicación no se compilará durante la implementación, se diferirá para compilarse según demanda cada vez que se produzca la primera solicitud y luego se almacenará en caché como cualquier otro recurso de su tipo.

Crear un constructor bajo demanda

En primer lugar, agregue un paquete netlify/functions como devDependencya su proyecto:

yarn add -D @netlify/functions

Una vez hecho esto, es lo mismo que crear una nueva función Netlify . Si no ha configurado un directorio específico para ellos, diríjase netlify/functions/y cree un archivo con cualquier nombre para su constructor.

import type { Handler } from '@netlify/functions'import { builder } from '@netlify/functions'const myHandler: Handler = async (event, context) = { return { statusCode: 200, body: JSON.stringify({ message: 'Built on-demand! ' }), }}export const handler = builder(myHandler)

Como puede ver en el fragmento anterior, el generador bajo demanda se separa de una función Netlify normal porque envuelve su controlador dentro de un builder()método. Este método conecta nuestra función con las tareas de compilación. Y eso es todo lo que necesita para aplazar una parte de su solicitud para su construcción sólo cuando sea necesario. ¡Pequeñas construcciones incrementales desde el principio!

Next.js en Netlify

Para crear una aplicación Next.js en Netlify, hay dos complementos importantes que se deben agregar para tener una mejor experiencia en general: Netlify Plugin Cache Next.js y Essential Next-on-Netlify . El primero almacena en caché su NextJS de manera más eficiente y debe agregarlo usted mismo, mientras que el segundo realiza algunos pequeños ajustes en la forma en que se construye la arquitectura Next.js para que se adapte mejor a la de Netlify y esté disponible de forma predeterminada para cada nuevo proyecto que Netlify pueda identificar. usando Next.js. Resumen de Libros

Constructores bajo demanda con Next.js

Creación de rendimiento, rendimiento de implementación, almacenamiento en caché y experiencia de desarrollador. Todos estos son temas muy importantes, pero son muchos y lleva tiempo configurarlos correctamente. Luego llegamos a esa vieja discusión sobre centrarse en la experiencia del desarrollador en lugar de la experiencia del usuario. Que es el momento en que las cosas van a un lugar escondido en un trabajo atrasado para ser olvidadas. No precisamente.

 

Netlify te respalda. En solo unos pocos pasos, podemos aprovechar todo el poder de Jamstack en nuestra aplicación Next.js. Es hora de arremangarse y ponerlo todo junto ahora.

Definición de rutas prerenderizadas

Si ha trabajado antes con la generación estática dentro de Next.js, probablemente haya oído hablar del getStaticPathsmétodo. Este método está destinado a rutas dinámicas (plantillas de página que representarán una amplia gama de páginas). Sin insistir demasiado en las complejidades de este método, es importante tener en cuenta que el tipo de retorno es un objeto con 2 claves, como en nuestra prueba de concepto, este será el archivo de ruta dinámica [Pokémon] :

export async function getStaticPaths() { return { paths: [], fallback: 'blocking', }}
  • pathses arrayrealizar todas las rutas que coincidan con esta ruta, que se prerenderizarán
  • fallbacktiene 3 valores posibles: bloqueo, trueofalse

En nuestro caso, lo nuestro getStaticPathses determinante:

  1. No se prerenderizarán rutas;
  2. Siempre que se llame a esta ruta, no brindaremos una plantilla alternativa, representaremos la página bajo demanda y mantendremos al usuario esperando, bloqueando la aplicación para que no pueda hacer nada más.

Cuando utilice On-Demand Builders, asegúrese de que su estrategia alternativa cumpla con los objetivos de su aplicación; los documentos oficiales de Next.js: los documentos alternativos son muy útiles.

Antes de On-Demand Builders, nuestro sistema getStaticPathsera ligeramente diferente:

export async function getStaticPaths() { const { pokemons } = await fetchPkmList() return { paths: pokemons.map(({ name }) = ({ params: { pokemon: name } })), fallback: false, }}

Estábamos recopilando una lista de todas las páginas de Pokémon que pretendíamos tener, asignamos todos los pokemonobjetos a solo un stringcon el nombre del Pokémon y reenviamos el { params }objeto que lo llevaba a getStaticProps. El nuestro fallbackestaba configurado en falseporque si una ruta no coincidía, queríamos que Next.js arrojara una 404: Not Foundpágina.

Puede consultar ambas versiones implementadas en Netlify:

  • Con On-Demand Builder: código , en vivo
  • Totalmente estático generado: código , en vivo

El código también es de código abierto en Github y puedes implementarlo fácilmente tú mismo para comprobar los tiempos de compilación. Y con esta cola, pasamos al siguiente tema.

Tiempos de construcción

Como se mencionó anteriormente, la demostración anterior es en realidad una prueba de concepto ; nada es realmente bueno o malo si no podemos medirlo. Para nuestro pequeño estudio, fui a la PokéAPI y decidí capturar todos los pokémons.

 

Para fines de reproducibilidad, limité nuestra solicitud (a 1000). En realidad, no están todos dentro de la API, pero exige que la cantidad de páginas sea la misma para todas las compilaciones, independientemente de si las cosas se actualizan en algún momento.

export const fetchPkmList = async () = { const resp = await fetch(`${API}pokemon?limit=${LIMIT}`) const { count, results, }: { count: number results: { name: string url: string }[] } = await resp.json() return { count, pokemons: results, limit: LIMIT, }}

Y luego lanzó ambas versiones en ramas separadas a Netlify, gracias a las implementaciones de vista previa, pueden coexistir básicamente en el mismo entorno. Para evaluar realmente la diferencia entre ambos métodos, el enfoque ODB fue extremo: no se prerenderizaron páginas para esa ruta dinámica. Aunque no se recomienda para escenarios del mundo real (querrá renderizar previamente sus rutas con mucho tráfico), marca claramente el rango de mejora del rendimiento en tiempo de construcción que podemos lograr con este enfoque.

Estrategia Número de páginas Número de activos Tiempo de construcción Tiempo total de implementación
Totalmente estática generada 1002 1005 2 minutos 32 segundos 4 minutos 15 segundos
Constructores bajo demanda 2 0 52 segundos 52 segundos

Las páginas de nuestra pequeña aplicación PokéDex son bastante pequeñas, los recursos de imagen son muy reducidos, pero las ganancias en el tiempo de implementación son muy significativas. Si una aplicación tiene una cantidad media o grande de rutas, definitivamente vale la pena considerar la estrategia ODB.

Hace que sus implementaciones sean más rápidas y, por lo tanto, más confiables. El impacto en el rendimiento solo ocurre en la primera solicitud; a partir de la solicitud posterior, la página representada se almacenará en caché directamente en Edge, lo que hace que el rendimiento sea exactamente el mismo que el de la generación totalmente estática.

El futuro: renderizado persistente distribuido

El mismo día, se anunciaron los On-Demand Builders y se les dio acceso anticipado, Netlify también publicó su Solicitud de comentarios sobre el renderizado persistente distribuido (DPR) .

DPR es el siguiente paso para los constructores bajo demanda. Aprovecha las compilaciones más rápidas al utilizar pasos de compilación asincrónicos y luego almacenar en caché los activos hasta que realmente se actualicen. No más compilaciones completas para un sitio web de 10k páginas. DPR permite a los desarrolladores tener un control total sobre la construcción e implementación de sistemas a través de un almacenamiento en caché sólido y el uso de On-Demand Builders.

Imagínese este escenario: un sitio web de comercio electrónico tiene 10.000 páginas de productos, lo que significa que se necesitarían alrededor de 2 horas para crear la aplicación completa para su implementación. No necesitamos discutir lo doloroso que es esto.

Con DPR, podemos configurar las 500 páginas principales para desarrollarlas en cada implementación. Nuestras páginas de mayor tráfico siempre están listas para nuestros usuarios. Pero somos una tienda, es decir, cada segundo cuenta. Entonces, para las otras 9500 páginas, podemos configurar un enlace posterior a la compilación para activar sus creadores, implementando el resto de nuestras páginas de forma asincrónica y almacenando en caché de inmediato. Ningún usuario resultó herido, nuestro sitio web se actualizó con la compilación más rápida posible y todo lo demás que no existía en la memoria caché se almacenó.

Conclusión

Aunque muchos de los puntos de discusión en este artículo fueron conceptuales y la implementación aún está por definirse, estoy entusiasmado con el futuro de Jamstack. Los avances que estamos logrando como comunidad giran en torno a la experiencia del usuario final.

¿Cuál es su opinión sobre el renderizado persistente distribuido? ¿Ha probado On-Demand Builders en su aplicación? Déjame saber más en los comentarios o llámame en Twitter. ¡Tengo mucha curiosidad!

Referencias

  • “ Una guía completa para la regeneración estática incremental (ISR) con Next.js ”, Lee Robinson
  • " Construcciones más rápidas para sitios grandes en Netlify con creadores bajo demanda ", Asavari Tayal, Blog de Netlify
  • " Representación persistente distribuida: un nuevo enfoque Jamstack para compilaciones más rápidas ", Matt Biilmann, Blog de Netlify
  • “ Representación persistente distribuida (DPR) ”, Cassidy Williams, GitHub

(vf, il)Explora más en

  • pila de mermelada
  • Siguiente.js
  • javascript





Tal vez te puede interesar:

  1. ¿Deberían abrirse los enlaces en ventanas nuevas?
  2. 24 excelentes tutoriales de AJAX
  3. 70 técnicas nuevas y útiles de AJAX y JavaScript
  4. Más de 45 excelentes recursos y repositorios de fragmentos de código

Desglosando compilaciones voluminosas con Netlify y Next.js

Desglosando compilaciones voluminosas con Netlify y Next.js

Índice Construya una vez, actualice cuando sea necesario

programar

es

https://aprendeprogramando.es/static/images/programar-desglosando-compilaciones-voluminosas-con-netlify-y-next-1107-0.jpg

2024-04-04

 

Desglosando compilaciones voluminosas con Netlify y Next.js
Desglosando compilaciones voluminosas con Netlify y Next.js

Si crees que alguno de los contenidos (texto, imagenes o multimedia) en esta página infringe tus derechos relativos a propiedad intelectual, marcas registradas o cualquier otro de tus derechos, por favor ponte en contacto con nosotros en el mail [email protected] y retiraremos este contenido inmediatamente

 

 

Top 20