✨ Cómo funciona Next.js
Tags: nextjs, webdev, javascript, programming
Published: 2023-11-11 21:15:15

Next.js proporciona un marco de trabajo para estructurar tu aplicación y optimizaciones que ayudan tanto en el proceso de desarrollo como en la velocidad de la aplicación final.

En las próximas secciones, veremos lo que sucede con tu código de aplicación en las siguientes etapas:

- El entorno en el que se ejecuta tu código: Desarrollo vs. Producción.
- Cuándo se ejecuta tu código: Tiempo de compilación vs. Tiempo de ejecución.
- Dónde ocurre la representación: Cliente vs. Servidor.

Ahora, profundicemos en estos conceptos y discutamos algunos de los procesos que Next.js realiza en segundo plano.

## Entornos de desarrollo y producción
Puedes pensar en los entornos como el contexto en el que se ejecuta tu código.

Durante el desarrollo, estás construyendo y ejecutando la aplicación en tu máquina local. Pasar a producción es el proceso de preparar tu aplicación para ser implementada y consumida por los usuarios.

## Cómo se aplica esto a Next.js
Next.js proporciona características tanto para las etapas de desarrollo como para las de producción de una aplicación. Por ejemplo:

- En la etapa de desarrollo, Next.js se optimiza para el desarrollador y su experiencia al construir la aplicación. Viene con características que buscan mejorar la Experiencia del Desarrollador, como la integración incorporada de TypeScript y ESLint, Fast Refresh y más.
- En la etapa de producción, Next.js se optimiza para los usuarios finales y su experiencia al utilizar la aplicación. Su objetivo es transformar el código para que sea eficiente y accesible.

Dado que cada entorno tiene consideraciones y objetivos diferentes, hay mucho que debe hacerse para llevar una aplicación desde el desarrollo hasta la producción. Por ejemplo, el código de la aplicación debe ser compilado, empaquetado, minimizado y dividido en fragmentos.

## El Compilador de Next.js
Next.js se encarga en gran medida de estas transformaciones de código y de la infraestructura subyacente para facilitar que tu aplicación pase a producción.

Esto es posible porque Next.js tiene un compilador escrito en Rust, un lenguaje de programación de bajo nivel, y SWC, una plataforma que se puede utilizar para la compilación, minimización, empaquetado y más.

## ¿Qué es la Compilación?
Los desarrolladores escriben código en lenguajes más amigables para los desarrolladores, como JSX, TypeScript y versiones modernas de JavaScript. Si bien estos lenguajes mejoran la eficiencia y la confianza de los desarrolladores, deben compilarse a JavaScript antes de que los navegadores puedan entenderlos.

La compilación se refiere al proceso de tomar código en un lenguaje y convertirlo en otro lenguaje o en otra versión de ese lenguaje.

![Compilación](https://miro.medium.com/v2/resize:fit:828/format:webp/1*JjU5-QatkeQ3UH7HaN-EEA.png)

En Next.js, la compilación ocurre durante la etapa de desarrollo a medida que editas tu código y como parte del paso de compilación para preparar tu aplicación para la producción.

## ¿Qué es la Minificación (Minifying)?
Los desarrolladores escriben código optimizado para que sea legible por los humanos. Este código puede contener información adicional que no es necesaria para que el código se ejecute, como comentarios, espacios, sangrías y múltiples líneas.

![Minificación](https://miro.medium.com/v2/resize:fit:828/format:webp/1*m_LQJNavItF2b9uhjKoFVw.png)

La minificación es el proceso de eliminar el formato y los comentarios innecesarios del código sin cambiar la funcionalidad del mismo. El objetivo es mejorar el rendimiento de la aplicación al reducir el tamaño de los archivos.

En Next.js, los archivos de JavaScript y CSS se minifican automáticamente para la producción.

## ¿Qué es la Agrupación (Bundling)?
Los desarrolladores dividen su aplicación en módulos, componentes y funciones que se pueden utilizar para construir piezas más grandes de su aplicación. Exportar e importar estos módulos internos, así como paquetes externos de terceros, crea una compleja red de dependencias de archivos.

![Agrupación](https://miro.medium.com/v2/resize:fit:828/format:webp/1*bCzRmK_XvTdXLxfmSuhSRA.png)

La agrupación (bundling) es el proceso de resolver esta red de dependencias y fusionar (o ‘empaquetar’) los archivos (o módulos) en paquetes optimizados para el navegador, con el objetivo de reducir la cantidad de solicitudes de archivos cuando un usuario visita una página web.

## ¿Qué es la División de Código (Code Splitting)?
Por lo general, los desarrolladores dividen sus aplicaciones en varias páginas a las que se puede acceder desde diferentes URL. Cada una de estas páginas se convierte en un punto de entrada (entry point) único en la aplicación.

La división de código es el proceso de dividir el paquete de la aplicación en fragmentos más pequeños requeridos por cada punto de entrada. El objetivo es mejorar el tiempo de carga inicial de la aplicación cargando solo el código necesario para ejecutar esa página.

![División de código](https://miro.medium.com/v2/resize:fit:828/format:webp/1*vQ18sNq9zYVNg7oyTq3EJw.png)

Next.js tiene soporte incorporado para la división de código. Cada archivo dentro de su directorio de páginas (pages/) se dividirá automáticamente en su propio paquete JavaScript durante el paso de compilación.

Además:

- Cualquier código compartido entre las páginas también se divide en otro paquete para evitar la descarga repetida del mismo código al navegar a otras páginas.
- Después de la carga inicial de la página, Next.js puede comenzar a precargar el código de otras páginas a las que es probable que los usuarios naveguen.
- Las importaciones dinámicas son otra forma de dividir manualmente qué código se carga inicialmente.

## Tiempo de Compilación (Build Time) y Tiempo de Ejecución (Run Time)
El tiempo de compilación (o paso de compilación) es el nombre dado a una serie de pasos que preparan el código de su aplicación para la producción.

Cuando construye su aplicación, Next.js transformará su código en archivos optimizados para la producción listos para ser implementados en servidores y consumidos por usuarios. Estos archivos incluyen:

- Archivos HTML para páginas generadas estáticamente.
- Código JavaScript para renderizar páginas en el servidor.
- Código JavaScript para hacer que las páginas sean interactivas en el cliente.
- Archivos CSS.

El tiempo de ejecución (o tiempo de solicitud) se refiere al período de tiempo en el que su aplicación se ejecuta en respuesta a la solicitud de un usuario, después de que su aplicación haya sido construida e implementada.

## Cliente y Servidor
En el contexto de las aplicaciones web, el cliente se refiere al navegador en el dispositivo de un usuario que envía una solicitud a un servidor para obtener el código de su aplicación. Luego, convierte la respuesta que recibe del servidor en una interfaz con la que el usuario puede interactuar.

![Cliente y Servidor](https://miro.medium.com/v2/resize:fit:828/format:webp/1*CXy69CiJqq37XEKHs9_a9A.png)

El servidor se refiere a la computadora en un centro de datos que almacena el código de su aplicación, recibe solicitudes de un cliente, realiza algunos cálculos y envía una respuesta adecuada.

## ¿Qué es el Renderizado?
Hay una unidad inevitable de trabajo para convertir el código que escribes en React en la representación HTML de tu interfaz de usuario. Este proceso se llama renderizado.

El renderizado puede tener lugar en el servidor o en el cliente. Puede ocurrir de antemano en el momento de la construcción (build time) o en cada solicitud en tiempo de ejecución.

Con Next.js, están disponibles tres tipos de métodos de renderizado: Server-Side Rendering, Static Site Generation y Client-Side Rendering.

## Pre-Renderizado
El Server-Side Rendering y la Static Site Generation también se conocen como Pre-Renderizado porque la obtención de datos externos y la transformación de los componentes de React en HTML ocurren antes de que el resultado se envíe al cliente.

## Client-Side Rendering vs. Pre-Rendering
En una aplicación React estándar, el navegador recibe una carcasa HTML vacía del servidor junto con las instrucciones de JavaScript para construir la interfaz de usuario. Esto se llama renderizado en el lado del cliente porque el trabajo de renderizado inicial ocurre en el dispositivo del usuario.

![Client-Side Rendering](https://miro.medium.com/v2/resize:fit:828/format:webp/1*KPy9X-3ld5a3j26lNozD1A.png)

> Nota: Puedes optar por utilizar el renderizado en el lado del cliente para componentes específicos en tu aplicación Next.js eligiendo recuperar datos con useEffect() de React o un gancho de obtención de datos como useSWR.

En cambio, Next.js pre-renderiza automáticamente cada página. El pre-renderizado significa que el HTML se genera de antemano, en un servidor, en lugar de hacerlo todo con JavaScript en el dispositivo del usuario.

En la práctica, esto significa que para una aplicación completamente renderizada en el lado del cliente, el usuario verá una página en blanco mientras se realiza el trabajo de renderizado. En comparación con una aplicación pre-renderizada, donde el usuario verá el HTML construido:

![Pre-Rendering](https://miro.medium.com/v2/resize:fit:828/format:webp/1*McnMIkQcR2in2M5WF6gWXQ.png)

Discutamos los dos tipos de pre-renderizado:

## Server-Side Rendering
Con el renderizado en el lado del servidor, el HTML de la página se genera en un servidor para cada solicitud. El HTML generado, los datos JSON y las instrucciones de JavaScript para hacer que la página sea interactiva se envían al cliente.

En el cliente, se utiliza el HTML para mostrar una página rápida pero no interactiva, mientras que React utiliza los datos JSON e instrucciones de JavaScript para hacer que los componentes sean interactivos (por ejemplo, adjuntar controladores de eventos a un botón). A este proceso se le llama hidratación.

En Next.js, puedes optar por renderizar en el lado del servidor utilizando getServerSideProps.

> Nota: React 18 y Next 12 introducen una versión alfa de React server components. Los componentes del servidor se renderizan completamente en el servidor y no requieren JavaScript en el lado del cliente para renderizar. Además, los componentes del servidor permiten a los desarrolladores mantener parte de la lógica en el servidor y solo enviar el resultado de esa lógica al cliente. Esto reduce el tamaño del paquete enviado al cliente y mejora el rendimiento del renderizado en el lado del cliente. Obtén más información sobre los componentes del servidor de React aquí.

## Static Site Generation
Con la generación de sitios estáticos, el HTML se genera en el servidor, pero a diferencia del renderizado en el lado del servidor, no hay servidor en tiempo de ejecución. En su lugar, el contenido se genera una sola vez, en el momento de la construcción (build time), cuando se despliega la aplicación, y el HTML se almacena en una CDN y se reutiliza para cada solicitud.

En Next.js, puedes optar por generar páginas de forma estática utilizando getStaticProps.

> Nota: Puedes utilizar la “Regeneración Estática Incremental” para crear o actualizar páginas estáticas después de haber construido tu sitio. Esto significa que no tienes que reconstruir todo tu sitio si tus datos cambian.

La belleza de Next.js es que puedes elegir el método de renderizado más apropiado para tu caso de uso en particular, ya sea Generación de Sitio Estático, Renderizado en el Lado del Servidor o Renderizado en el Lado del Cliente. Para obtener más información sobre qué método de renderizado es adecuado para tu caso de uso específico, consulta la documentación sobre la obtención de datos (data fetching).

## ¿Qué es la Red?
Es útil saber dónde se almacena y se ejecuta el código de tu aplicación una vez que se despliega en la red. Puedes pensar en la red como una serie de computadoras interconectadas (o servidores) capaces de compartir recursos. En el caso de una aplicación Next.js, tu código de aplicación puede distribuirse en servidores de origen, redes de distribución de contenido (CDN) y el borde (Edge). Veamos qué significa cada uno de estos términos:

## Servidores de Origen
Como discutimos anteriormente, el término “servidor” se refiere al ordenador principal que almacena y ejecuta la versión original de tu código de aplicación.

Usamos el término “origen” para distinguir este servidor de los otros lugares donde se puede distribuir el código de la aplicación, como los servidores de CDN y los servidores de borde.

Cuando un servidor de origen recibe una solicitud, realiza algunos cálculos antes de enviar una respuesta. El resultado de este trabajo de cálculo se puede mover a un CDN (Red de Distribución de Contenido).

## Red de Distribución de Contenido (CDN)
Las CDNs almacenan contenido estático (como archivos HTML e imágenes) en múltiples ubicaciones de todo el mundo y se colocan entre el cliente y el servidor de origen. Cuando llega una nueva solicitud, la ubicación del CDN más cercana al usuario puede responder con el resultado en caché.


![Content Delivery Network](https://miro.medium.com/v2/resize:fit:828/format:webp/1*awae4kKKZxZqgtnsKNNKpg.png)

Esto reduce la carga en el origen porque el cálculo no tiene que realizarse en cada solicitud. También hace que sea más rápido para el usuario porque la respuesta proviene de una ubicación geográficamente más cercana a ellos.

En Next.js, dado que el pre-renderizado se puede realizar de antemano, las CDNs son adecuadas para almacenar el resultado estático del trabajo, lo que hace que la entrega de contenido sea más rápida.

## El Borde (Edge)
El borde es un concepto generalizado para el límite (o borde) de la red, más cercano al usuario. Las CDNs podrían considerarse parte de “el borde” porque almacenan contenido estático en el borde de la red.

Similar a las CDNs, los servidores de borde se distribuyen en múltiples ubicaciones de todo el mundo. Pero a diferencia de las CDNs, que almacenan contenido estático, algunos servidores de borde pueden ejecutar pequeños fragmentos de código.

Esto significa que tanto el almacenamiento en caché como la ejecución de código se pueden realizar en el borde más cercano al usuario.

Al trasladar parte del trabajo que tradicionalmente se realizaba en el lado del cliente o del servidor al borde, puedes hacer que tu aplicación sea más eficiente, ya que reduce la cantidad de código enviado al cliente y parte de la solicitud del usuario no tiene que ir todo el camino de regreso al servidor de origen, lo que reduce la latencia. Consulta ejemplos de uso del borde con Next.js aquí.

En Next.js, puedes ejecutar código en el borde con Middleware y pronto con React Server Components.