No faltan bibliotecas JavaScript y frameworks para los desarrolladores web modernos. Una de las bibliotecas más omnipresentes es React, que Facebook (ahora Meta) creó para ayudar a crear aplicaciones ricas en funciones. Las aplicaciones React se ejecutan tradicionalmente en navegadores web, pero el framework Next.js extiende la funcionalidad de React del lado del servidor a través del entorno de ejecución JavaScript Node.js.

En este artículo, examinaremos Next.js y React para que puedas decidir si son adecuados para tu próximo proyecto.

Next.js y React: JavaScript al Siguiente Nivel

Una encuesta de SlashData de 2022 reveló que hay más de 17 millones de programadores de JavaScript en todo el mundo, a la cabeza de un grupo que incluye lenguajes populares como Python y Java. JavaScript puede utilizarse tanto en el lado del cliente como en el del servidor, y esta versatilidad significa que los desarrolladores pueden crear aplicaciones completas utilizando un solo lenguaje de programación.

Gráfico que muestra el número de programadores que utilizan varios lenguajes sugiere que muchos de ellos tienen dudas sobre Next.js vs React.
Encuesta de Slash/Data sobre los lenguajes utilizados por los programadores en 2022. (Fuente: Statista)

La introducción de bibliotecas JavaScript como React y frameworks como Next.js potenció aún más ese desarrollo. Estas bibliotecas y frameworks proporcionan funciones que simplifican la integración de frontend y backend. Además, los desarrolladores pueden ampliar las capacidades de JavaScript utilizando gestores de paquetes como npm (el gestor de paquetes de Node.js) para instalar bibliotecas y herramientas JavaScript. Estos recursos proporcionan funciones sofisticadas que reducen la cantidad de código que tienes que escribir tú mismo.

La extensibilidad de JavaScript significa que un conocimiento exhaustivo de sus herramientas más comunes es clave para tu éxito como desarrollador web.

¿Qué Es Next.js?

Lanzado inicialmente en 2016 por Vercel, Next.js es un framework React de código abierto que proporciona los bloques de construcción para crear aplicaciones web de alto rendimiento. Desde entonces, lo han adoptado grandes empresas como Twitch, TikTok y Uber, por nombrar algunas.

Next.js ofrece una de las mejores experiencias para desarrolladores a la hora de crear aplicaciones rápidas y aptas para SEO. A continuación enumeramos algunas características de Next.js que lo convierten en un framework de producción excepcional:

  • Funciones de renderizado híbrido
  • División automática del código
  • Optimización de imágenes
  • Soporte integrado para preprocesadores CSS y bibliotecas CSS-in-JS
  • Enrutamiento integrado

Estas características ayudan a los desarrolladores de Next.js a ahorrar un tiempo considerable en la configuración y la creación de herramientas. Puede pasar directamente a construir tu aplicación, que podría soportar proyectos como los siguientes:

  • Tiendas de comercio electrónico
  • Blogs
  • Paneles de control
  • Aplicaciones de una sola página
  • Interfaces de usuario interactivas
  • Sitios web estáticos

¿Qué Es React?

React es una biblioteca JavaScript que se utiliza para crear interfaces de usuario dinámicas. Además de crear interfaces web, puedes crear aplicaciones móviles utilizando React Native.

Algunas de las ventajas de utilizar React son:

  • Mejora del rendimiento: En lugar de actualizar cada componente en el DOM, React utiliza un DOM virtual para actualizar solo los componentes modificados.
  • Muy basado en componentes: Una vez creado un componente, puedes reutilizarlo repetidamente.
  • Fácil depuración: Las aplicaciones React utilizan un flujo de datos unidireccional: solo de los componentes padre a los hijos.

Next.js vs React

Aunque los desarrolladores suelen utilizar Next.js y React con el mismo propósito, existen algunas diferencias fundamentales entre ambos.

Facilidad de Uso

Es fácil empezar con Next.js y React. Cada uno requiere ejecutar comandos sencillos en tu terminal utilizando npx, que forma parte de npm para Node.js.

Para Next.js, el comando más sencillo es:

npx create-next-app

Sin argumentos adicionales para create-next-app, la instalación se realizará en modo interactivo. Se te pedirá un nombre de proyecto (que se utilizará para el directorio del proyecto), y si quieres incluir soporte para TypeScript y el linter de código ESLint.

Tendrá un aspecto similar al siguiente

Captura de pantalla de una aplicación Next.js creada con npx.
Creando una aplicación Next.js en modo interactivo.

Al inicializar una instancia de React, el comando más sencillo incluye un nombre para el directorio del proyecto:

npx create-react-app new-app

Esto genera una carpeta que contiene todas las configuraciones y dependencias iniciales necesarias:

Captura de pantalla de un proyecto React creado con npx.
Crear un proyecto React en la línea de comandos del terminal.

Aunque ambos facilitan el comienzo, recuerda que Next.js está construido sobre React. Por tanto, no puedes aprender Next.js sin aprender primero React y comprender cómo funciona. Afortunadamente, React tiene una curva de aprendizaje suave y es ideal para principiantes.

También es importante tener en cuenta que React es relativamente poco estructurado. Debes instalar y configurar un enrutador React y decidir cómo gestionar la obtención de datos, la optimización de imágenes y la división del código. Esta configuración requiere que instales y configures bibliotecas y herramientas adicionales.

En cambio, Next.js viene con estas herramientas preinstaladas y preconfiguradas. Con Next.js, cualquier archivo añadido a la carpeta pages sirve automáticamente como ruta. Gracias a este soporte incorporado, Next.js es más fácil de trabajar a diario, lo que te permite empezar a programar la lógica de tu aplicación inmediatamente.

Características de Next.js y React

Dado que Next.js se basa en React, ambos comparten algunas características. Sin embargo, Next.js va un paso más allá e incluye funciones adicionales como enrutamiento, división de código, renderizado previo y compatibilidad con API. Estas son funciones que tendrás que configurar tú mismo cuando utilices React.

Obtención de Datos

React renderiza los datos en el lado del cliente. El servidor envía archivos estáticos al navegador, y luego el navegador obtiene los datos de las API para rellenar la aplicación. Este proceso reduce el rendimiento de la aplicación y proporciona una mala experiencia al usuario, ya que la aplicación se carga lentamente. Next.js resuelve este problema mediante el pre-renderizado.

Con el pre-renderizado, el servidor realiza las llamadas a las API necesarias y obtiene los datos antes de enviar la aplicación al navegador. De este modo, el navegador recibe páginas web listas para ser renderizadas.

El pre-renderizado puede referirse a la generación de sitios estáticos (SSG) o a la renderización del lado del servidor (SSR). En SSG, las páginas HTML se generan en tiempo de construcción y se reutilizan para múltiples peticiones. Next.js puede generar páginas HTML con o sin datos.

A continuación se muestra un ejemplo de cómo Next.js genera páginas sin datos:

function App() {
  return <div>Welcome</div>
}
export default App

Para páginas estáticas que consumen datos externos, utiliza la función getStaticProps(). Una vez que exportes getStaticProps() desde una página, Next.js pre-renderizará la página utilizando los accesorios que devuelve. Esta función siempre se ejecuta en el servidor, así que utiliza getStaticProps() cuando los datos que utiliza la página estén disponibles en el momento de la construcción. Por ejemplo, puedes utilizarla para obtener entradas de blog de un CMS.

const Posts= ({ posts }) => {
    return (
        <div className={styles.container}>
            {posts.map((post, index) => (
                // render each post
            ))}
        </div>
    );
  };

export const getStaticProps = async () => {
    const posts = getAllPosts();
    return {
        props: { posts },
    };
};

En situaciones en las que las rutas de la página dependan de datos externos, utiliza la función getStaticPaths(). Así, para crear una ruta basada en el ID del post, exporta el getStaticPaths() de la página.

Por ejemplo, podrías exportar getStaticPaths() desde pages/posts/[id].js como se muestra a continuación.

export getStaticPaths = async()  => {
  // Get all the posts
  const posts = await getAllPosts()

  // Get the paths you want to pre-render based on posts
  const paths = posts.map((post) => ({
    params: { id: post.id },
  }))
  return { paths, fallback: false }
}

getStaticPaths() suele ir emparejado con getStaticProps(). En este ejemplo, utilizarías getStaticProps() para obtener los detalles del ID en la ruta.

export const getStaticProps = async ({ params }) => {
    const post = await getSinglePost(params.id);
    return {
        props: { post }
    };
};

En SSR, los datos se obtienen en el momento solicitado y se envían al navegador. Para utilizar SSR, exporta la función getServerSide() props de la página que quieras renderizar. El servidor llama a esta función en cada petición, lo que hace que SSR sea útil para páginas que consumen datos dinámicos.

Por ejemplo, puedes utilizarla para obtener datos de una API de noticias.

const News = ({ data }) => {
    return (
        // render data
    );
  };

export async function getServerSideProps() {
    const res = await fetch(`https://app-url/data`)
    const data = await res.json()
    return { props: { data } }
}

Los datos se obtienen en cada petición y se pasan al componente Noticias mediante props.

División del Código

La división del código consiste en dividir el código en trozos que el navegador pueda cargar cuando lo solicite. Reduce la cantidad de código que se envía al navegador durante la carga inicial, ya que el servidor sólo envía lo que el usuario necesita. Bundlers como Webpack, Rollup y Browserify admiten la división de código en React.

Next.js admite la división de código desde el principio.

Con Next.js, cada página se divide en código, y añadir páginas a la aplicación no aumenta el tamaño del paquete. Next.js también admite importaciones dinámicas, lo que te permite importar módulos JavaScript y cargarlos dinámicamente durante el tiempo de ejecución. Las importaciones dinámicas contribuyen a acelerar la velocidad de las páginas porque los paquetes se cargan de forma perezosa.

Por ejemplo, en el componente Home de abajo, el servidor no incluirá el componente hero en el paquete inicial.

const DynamicHero = dynamic(() => import('../components/Hero'), {
  suspense: true,
})

export default function Home() {
  return (
    <Suspense fallback={`Loading...`}>
      <DynamicHero />
    </Suspense>
  )
}

En su lugar, el elemento » fallback » será renderizado antes de que el componente hero sea cargado.

Soporte de API en Next.js vs React

La función de enrutamiento API de Next.js te permite escribir código backend y frontend en la misma base de código. Cualquier página guardada en la carpeta /pages/api/ se asigna a la ruta /api/*, y Next.js la trata como un endpoint de la API.

Por ejemplo, puedes crear una ruta API pages/api/user.js que devuelva el nombre del usuario actual de esta forma:

export default function user(req, res) {
    res.status(200).json({ username: 'Jane' });
}

Si visitas la URL https://app-url/api/user, verás el objeto nombre de usuario.

{
        username: 'Jane'
}

Las rutas API son útiles cuando quieres enmascarar la URL de un servicio al que estás accediendo o quieres mantener en secreto variables de entorno sin programar toda una aplicación backend.

Rendimiento

Next.js es indudablemente superior en su capacidad para crear aplicaciones de mejor rendimiento con un proceso simplificado. Las aplicaciones SSR y SSG Next.js rinden mejor que las aplicaciones React de renderizado del lado del cliente (CSR). Al obtener los datos en el servidor y enviar todo lo que el navegador necesita para renderizar, Next.js elimina la necesidad de una solicitud de obtención de datos a las API. Esto significa tiempos de carga más rápidos.

Además, como Next.js admite el enrutamiento del lado del cliente. El navegador no tiene que obtener datos del servidor cada vez que un usuario navega a otra ruta. Además, el componente de imagen de Next.js permite la optimización automática de imágenes. Las imágenes sólo se cargan cuando entran en la ventana gráfica. Cuando es posible, Next.js también sirve imágenes en formatos modernos como WebP.

Next.js también proporciona optimizaciones de fuentes, precarga inteligente de rutas y optimizaciones de paquetes. Estas optimizaciones no están disponibles automáticamente en React.

Soporte

Dado que React existe desde hace más tiempo que Next.js, cuenta con una comunidad más extensa. Sin embargo, muchos desarrolladores de React están adoptando Next.js, por lo que esa comunidad está creciendo constantemente. Los desarrolladores encuentran más fácilmente las soluciones existentes a los problemas que encuentran, en lugar de tener que crear soluciones desde cero.

Next.js también cuenta con una excelente documentación con ejemplos completos y fáciles de entender. A pesar de su popularidad, la documentación de React no es tan navegable.

Resumen

Elegir Next.js o React se reduce a los requisitos de una aplicación.

Next.js mejora las capacidades de React proporcionando estructura y herramientas que mejoran el rendimiento. Estas herramientas, como el enrutamiento, la división de código y la optimización de imágenes, están integradas en Next.js, lo que significa que los desarrolladores no tienen que configurar nada manualmente. Gracias a estas funciones, Next.js es fácil de usar, y los desarrolladores pueden empezar a programar la lógica empresarial inmediatamente.

Debido a las diferentes opciones de renderizado, Next.js es adecuado para aplicaciones renderizadas en el lado del servidor o aplicaciones que combinan la generación estática y el renderizado en el lado del servidor de Node.js. Además, gracias a la función de optimización que proporciona Next.js, es perfecto para sitios que necesitan ser rápidos, como las tiendas de comercio electrónico.

React es una biblioteca JavaScript que puede ayudarte a crear y escalar aplicaciones front-end robustas. Su sintaxis también es sencilla, especialmente para desarrolladores con conocimientos de JavaScript. Además, tienes control sobre las herramientas que utilizas en tu aplicación y sobre cómo las configuras.

¿Planeas tu propia aplicación para dominar el mundo? Profundiza en el enfoque de Kinsta sobre el alojamiento de aplicaciones Node.js para servicios compatibles con React y Next.js.

Salman Ravoof

Salman Ravoof is a self-taught web developer, writer, creator, and a huge admirer of Free and Open Source Software (FOSS). Besides tech, he's excited by science, philosophy, photography, arts, cats, and food. Learn more about him on his website, and connect with Salman on Twitter.