BackVolver al blog

Next.js 10

Next.js 10 introduce Optimización de Imágenes Integrada, Enrutamiento Internacionalizado, Análisis de Next.js, Soporte para React 17, ¡y mucho más!

Estamos emocionados de presentar Next.js 10, que incluye:

Componente de Imagen Integrado y Optimización Automática de Imágenes

Nuestro objetivo con Next.js es mejorar dos cosas: la Experiencia del Desarrollador y la Experiencia del Usuario.

Este año ya hemos invertido fuertemente tanto en la Experiencia del Desarrollador como en mejorar el rendimiento para todas las aplicaciones Next.js. Nos enfocamos en reducir la cantidad de JavaScript que el navegador tiene que cargar.

Introdujimos más de 20 nuevas características que mejoran el rendimiento y la experiencia del desarrollador. Al mismo tiempo, el tamaño de JavaScript del núcleo de Next.js se ha reducido en un 16%.

En enero, introdujimos una nueva estrategia de división de código JavaScript de primer nivel en colaboración con el equipo de Google Chrome.

Por ejemplo, Barnebys vio una disminución del 23% en el tamaño de la aplicación, y Sumup tuvo una reducción del 70% en el tamaño de su paquete JavaScript más grande. Estas mejoras se lograron sin cambiar ningún código en sus aplicaciones Next.js.

Las empresas adoptaron esta nueva estrategia automáticamente simplemente actualizando Next.js a la última versión.

Imágenes en la Web

Si bien nuestro enfoque en reducir la cantidad de JavaScript que el navegador tiene que cargar ha dado resultados, la web no es solo JavaScript: también es marcado e imágenes.

Las imágenes ocupan el 50% del total de bytes en las páginas web.

Las imágenes tienen un gran impacto en el Largest Contentful Paint (LCP) ya que a menudo son el elemento visible más grande cuando se carga una página. LCP es una métrica de Web Vitals que Google usará en su ranking de búsqueda muy pronto.

La mitad de todas las imágenes tienen un tamaño superior a un megabyte, lo que significa que no están optimizadas para mostrarse en la web.

Hoy en día los usuarios navegan por la web usando sus teléfonos, tabletas y portátiles, pero las imágenes siguen siendo de un tamaño único. Por ejemplo: los sitios cargan una imagen de 2000 por 2000 píxeles, pero los teléfonos solo la muestran como 100 por 100 píxeles.

Además, el 30% de las imágenes en las páginas web están fuera del viewport inicial, lo que significa que el navegador carga imágenes que el usuario no ve hasta que se desplaza más abajo en la página.

A menudo las imágenes no tienen propiedades width y height, lo que hace que salten cuando se carga la página. Esto perjudica la métrica Cumulative Layout Shift de Web Vitals.

El 99.7% de las imágenes en los sitios web no usan formatos modernos como WebP.

Para usar imágenes en páginas web de manera performante hay que considerar muchos aspectos: tamaño, peso, carga diferida y formatos modernos de imagen.

Los desarrolladores tienen que configurar herramientas de construcción complicadas para optimizar imágenes, pero esas herramientas generalmente no cubren imágenes enviadas por usuarios desde una fuente de datos externa, lo que hace imposible optimizar todas las imágenes.

Esta tarea de desarrollo imposible inevitablemente conduce a una experiencia frustrante para el usuario final.

Componente de Imagen de Next.js

Nos complace anunciar nuestra solución para imágenes performantes en la web: el Componente de Imagen de Next.js y la Optimización Automática de Imágenes.

En su forma más básica, el Componente de Imagen de Next.js es simplemente un reemplazo directo del elemento HTML <img>, evolucionado para la web moderna.

<img
  src="/profile-picture.jpg"
  width="400"
  height="400"
  alt="Profile Picture"
/>
import Image from 'next/image';
<Image
  src="/profile-picture.jpg"
  width="400"
  height="400"
  alt="Profile Picture"
/>;

El equipo de Google Chrome ayudó a crear este componente React para mejorar el rendimiento de la página haciendo que las mejores prácticas sean la opción predeterminada.

Cuando se usa el componente next/image, las imágenes se cargan de forma diferida automáticamente, lo que significa que solo se renderizan cuando el usuario está cerca de ver la imagen. Esto evita cargar ese 30% de imágenes fuera del viewport inicial.

Se aplican dimensiones a las imágenes, lo que permite a los navegadores renderizar inmediatamente el espacio necesario para la imagen en lugar de que aparezca de golpe cuando se carga, evitando el desplazamiento del diseño.

Mientras que width y height en el elemento HTML <img> pueden causar problemas con diseños responsivos, este no es el caso al usar next/image. Cuando se usa next/image, la imagen se hace automáticamente responsiva según la relación de aspecto de las propiedades width y height proporcionadas.

Los desarrolladores pueden marcar imágenes que están en el viewport inicial, permitiendo que Next.js las precargue automáticamente. La precarga de imágenes en el viewport inicial ha mostrado mejoras en el Largest Contentful Paint de hasta un 50%.

Optimización Automática de Imágenes

Incluso con estas mejoras en comparación con el elemento HTML <img>, todavía hay un problema importante. La imagen de 2000 por 2000 píxeles se envía a teléfonos que renderizan una imagen más pequeña.

Con Next.js 10 también estamos resolviendo ese problema. El componente next/image generará automáticamente tamaños más pequeños mediante la Optimización de Imágenes Integrada.

La Optimización de Imágenes Integrada sirve automáticamente las imágenes en formatos modernos como WebP, que es aproximadamente un 30% más pequeño que JPEG, si el navegador lo admite. También permite que Next.js adopte automáticamente futuros formatos de imagen y los sirva a navegadores que admitan esos formatos.

La Optimización de Imágenes funciona con cualquier fuente de imagen. Incluso si las imágenes provienen de una fuente de datos externa, como un CMS, se optimizan.

En lugar de optimizar imágenes en tiempo de construcción, Next.js 10 optimiza imágenes bajo demanda, según las solicitudes de los usuarios. A diferencia de los generadores de sitios estáticos y las soluciones solo estáticas, tus tiempos de construcción no aumentan, ya sea que envíes 10 imágenes o 10 millones de imágenes.

Conclusión

El nuevo componente next/image y la Optimización Automática de Imágenes son poderosas primitivas nuevas que mejorarán enormemente la experiencia del usuario.

El componente next/image maneja la carga diferida automática, la precarga de imágenes críticas, el tamaño correcto en todos los dispositivos y admite automáticamente formatos modernos. Estas características funcionan con imágenes de cualquier fuente.

Esperamos ver cuánto más rápida se vuelve tu experiencia de usuario con estas nuevas primitivas.

Para más detalles, consulta la documentación del Componente de Imagen de Next.js y la Optimización Automática de Imágenes.

Enrutamiento Internacionalizado

Este año, varias empresas y miembros de la comunidad ayudaron a nuestro equipo a comprender cuán importante es la internacionalización.

Por ejemplo, aprendimos que el 72% de los consumidores es más probable que permanezca en tu sitio si está traducido y el 55% de los consumidores dijo que solo compra en sitios de comercio electrónico en su idioma nativo.

Si planeas llegar al mercado en un país diferente, internacionalizar tu proyecto es crítico para el éxito.

La internacionalización de un proyecto tiene dos pilares principales: Traducciones y Enrutamiento.

Muchas bibliotecas React preparan aplicaciones para ser traducidas, pero la mayoría espera que manejes el enrutamiento manualmente y generalmente solo funcionan con una estrategia de renderizado.

Es por eso que, como parte de Next.js 10, estamos lanzando soporte integrado para enrutamiento internacionalizado y detección de idioma.

Este soporte integrado para enrutamiento internacionalizado admite la estrategia híbrida de Next.js, por lo que puedes elegir entre Generación Estática o Renderizado del Servidor por página.

Next.js 10 admite las dos estrategias de enrutamiento más comunes: enrutamiento por subruta y enrutamiento por dominio.

Para ambas estrategias, comienzas configurando los locales en la configuración de Next.js.

next.config.js
module.exports = {
  i18n: {
    locales: ['en', 'nl'],
    defaultLocale: 'en',
  },
};

Los locales son Identificadores de Localidad UTS, un formato estandarizado para definir localidades.

Generalmente un Identificador de Localidad se compone de un idioma, región y script separados por un guión: idioma-región-script. La región y el script son opcionales. Un ejemplo:

  • en-US - Inglés como se habla en Estados Unidos
  • nl-NL - Holandés como se habla en los Países Bajos
  • nl - Holandés, sin región específica

Una vez configurados tus locales, puedes elegir enrutamiento por subruta o por dominio.

Enrutamiento por subruta

El enrutamiento por subruta coloca el locale en la URL. Esto permite que todos los idiomas vivan en un solo dominio.

Por ejemplo, puedes insertar el locale en la URL como /nl-nl/blog y /en/blog.

Enrutamiento por dominio

El enrutamiento por dominio te permite mapear un locale a un dominio de primer nivel. Por ejemplo, example.nl se puede mapear al locale nl y example.com se puede mapear al locale en.

El enrutamiento por dominio requiere alguna configuración adicional para saber cómo enrutar los dominios:

next.config.js
module.exports = {
  i18n: {
    locales: ['en', 'nl'],
    domains: [
      {
        domain: 'example.com',
        defaultLocale: 'en',
      },
      {
        domain: 'example.nl',
        defaultLocale: 'nl',
      },
    ],
  },
};

Detección de Idioma

Next.js 10 tiene detección de idioma integrada en la ruta / basada en el encabezado Accept-Language, que todos los navegadores modernos admiten. Los locales configurados se compararán con el encabezado Accept-Language y luego se redirigirán según la estrategia configurada.

Optimización para Motores de Búsqueda

Como Next.js conoce el idioma de la página visitada por el usuario, agregará automáticamente el atributo lang a la etiqueta <html>.

Next.js no conoce las variantes de una página, por lo que depende de ti agregar las etiquetas meta hreflang usando next/head. Puedes aprender más sobre hreflang en la documentación de Google Webmasters.

El futuro de la internacionalización en Next.js

El Enrutamiento Internacionalizado es el primero de una serie de características que facilitarán la internacionalización y localización de tu proyecto. El Enrutamiento Internacionalizado permite la integración con la mayoría de las bibliotecas de internacionalización de React.

Para obtener más información sobre el Enrutamiento Internacionalizado, consulta la documentación de Enrutamiento Internacionalizado.

Next.js Speed Insights

En Vercel, sabemos que no puedes arreglar lo que no puedes medir.

Tus visitantes se han vuelto cada vez más sensibles al rendimiento del sitio. Más del 50% de ellos abandonará tu sitio web si tarda más de 3 segundos en cargar. Si estás en comercio electrónico, muchos han descubierto que mejorar el tiempo de carga en 1/10 de segundo resultó en un aumento del 1% en las conversiones.

Debido a lo crítico que es el rendimiento para tu éxito, estamos orgullosos de lanzar Next.js Speed Insights. La solución para rastrear métricas de rendimiento del mundo real y alimentar esas ideas de vuelta a tu flujo de trabajo de desarrollo.

Con Next.js Speed Insights:

En lugar de medir una vez, ahora medirás continuamente.

En lugar de medir en tu dispositivo de desarrollo, las mediciones provendrán de los dispositivos reales que tus visitantes están usando.

Next.js Speed Insights se trata de enfocarse en el panorama completo, comprender profundamente a tu audiencia y cómo funciona tu aplicación para tus usuarios.

Estamos tan convencidos de recopilar datos reales porque las causas del bajo rendimiento no siempre son las más obvias. Las regresiones de rendimiento pueden resultar de una variedad de lugares: scripts y hojas de estilo de terceros, o fuentes, imágenes y videos propios que son demasiado grandes o lentos.

Core Web Vitals

Google, en colaboración con el Web Performance Working Group, ha establecido un conjunto de métricas para medir con precisión cómo los usuarios experimentan el rendimiento de su sitio web: apropiadamente llamadas Web Vitals. Los Web Vitals son métricas que rastrean la velocidad de carga percibida, la capacidad de respuesta y la estabilidad visual de su sitio web: ¡los tres esenciales para la salud general del sitio web!

La velocidad de carga percibida se puede medir mediante Largest Contentful Paint (LCP), o cuando todo el contenido de la página se ha mostrado. Por ejemplo, cuando abro un enlace para comprar unos zapatos deportivos, el tiempo que pasa antes de que vea los zapatos, su precio y el botón de agregar al carrito es el LCP.

La capacidad de respuesta de la página se puede medir mediante First Input Delay (FID), que mide cuánto tiempo deben esperar sus usuarios para ver la reacción de su primera interacción con la página. Por ejemplo, el tiempo entre que hago clic en Agregar al carrito y el número de artículos en mi carrito aumenta es el FID.

Finalmente, la estabilidad visual se puede medir mediante Cumulative Layout Shift (CLS), o cuánto se mueven los elementos después de mostrarse al usuario. Por ejemplo, todos hemos experimentado la frustración de intentar hacer clic en un botón que se movió porque una imagen se cargó tarde: eso es el desplazamiento de diseño (layout shift).

La medición continua y el cumplimiento de estos Web Vitals para sus usuarios reales es crucial. Es la única manera de saber realmente cómo funciona su sitio para sus usuarios. El rendimiento de su sitio puede variar drásticamente según el dispositivo del usuario, sus condiciones de red o cómo interactúan con la página. Los sitios que cargan contenido personalizado o anuncios también pueden experimentar un rendimiento muy diferente de un usuario a otro.

Una prueba emulada no puede capturar estas señales importantes.

Next.js Speed Insights le permite capturar información del mundo real, en lugar de puntos de referencia sintéticos. Permite un flujo continuo de medición en lugar de depender de pruebas ocasionales, asegurando que sea parte de su flujo de trabajo de desarrollo.

Visite nextjs.org/analytics para aprender cómo habilitarlo en su aplicación ahora mismo.

Next.js Commerce

El comercio electrónico es uno de los usos más importantes de la web. Las nuevas características de Next.js 10 son herramientas poderosas para el comercio electrónico.

Es por eso que hoy, en colaboración con BigCommerce, lanzamos Next.js Commerce, el kit de inicio todo en uno de React para sitios de comercio electrónico. Con unos pocos clics, los desarrolladores de Next.js pueden clonarlo, implementarlo y personalizarlo por completo. Comience ahora en nextjs.org/commerce.

Soporte para React 17

React 17 no tuvo cambios disruptivos para Next.js, sin embargo, hubo algunos cambios de mantenimiento requeridos, como actualizar las dependencias peer. La nueva transformación JSX se habilita automáticamente cuando se usa React 17, no se necesitan cambios de configuración.

Todo lo que tiene que hacer para comenzar a usar React 17 es actualizar Next.js y React:

Terminal
npm install next@latest react@latest react-dom@latest

Actualización rápida (Fast Refresh) para getStaticProps / getServerSideProps

Al realizar ediciones en sus funciones getStaticProps y getServerSideProps, Next.js ahora volverá a ejecutar automáticamente la función y aplicará los nuevos datos. Esto le permite iterar más rápido sin tener que actualizar la página.

Para obtener más información sobre getStaticProps y getServerSideProps, puede leer la documentación de obtención de datos.

Actualización rápida (Fast Refresh) para MDX

Al usar Next.js con MDX a través de @next/mdx, los cambios en el contenido MDX ahora aprovecharán la actualización rápida (Fast Refresh), asegurando que el navegador no tenga que recargar la página al editar.

La documentación de @next/mdx lo guía sobre cómo configurar MDX con Next.js.

Importación de CSS desde componentes React de terceros

Ahora puede importar CSS de terceros dentro de componentes React. Esto permite dividir el código (code-splitting) de CSS destinado solo a un componente específico. Por ejemplo, ahora puede usar la biblioteca react-datepicker sin necesidad de importar el CSS en _app.js:

components/MyComponent.js
import DatePicker from 'react-datepicker';
import 'react-datepicker/dist/react-datepicker.css';
 
function MyComponent() {}

Puede consultar la documentación de soporte de CSS incorporado para obtener más información sobre cómo Next.js maneja las importaciones de CSS.

Resolución automática de href

Si ha utilizado rutas dinámicas antes, probablemente se ha encontrado con un caso en el que tuvo que proporcionar tanto una propiedad href como as a next/link. Se vería algo así:

<Link href="/categories/[slug]" as="/categories/books" />

Esto permitió que Next.js interpolará el href para los parámetros dinámicos, sin embargo, causaba fricción cuando los desarrolladores olvidaban agregar el as o agregaban el as en href, haciendo que las transiciones de página no utilizaran el enrutamiento del lado del cliente (client-side routing).

Hace unos meses nos propusimos resolver esta fricción para los desarrolladores, con el objetivo principal de mejorar la experiencia del desarrollador y la experiencia del usuario final. Trabajamos incrementalmente hacia una solución que permite que href se resuelva automáticamente.

Nos complace anunciar que, como parte de Next.js 10, ya no tiene que usar la propiedad as para la mayoría de los casos de uso. Eliminando fricciones para los desarrolladores y mejorando la experiencia del usuario final.

Este cambio es totalmente compatible con versiones anteriores. Si actualmente usa tanto href como as, se conserva el comportamiento existente.

Para adoptar la resolución automática de href, todo lo que tiene que hacer es cambiar su uso de next/link para usar solo href con el valor que anteriormente tenía en la propiedad as.

<Link href="/categories/books" />

Para obtener más información sobre next/link y el enrutamiento del lado del cliente (client-side routing), puede consultar la documentación de next/link.

CLI de @next/codemod

Nos comprometemos a garantizar que las actualizaciones de Next.js sean lo más fluidas posible mediante una amplia compatibilidad con versiones anteriores. Este compromiso comienza con la deprecación muy limitada de funciones mientras se introducen soluciones nuevas y mejores en su lugar. Además de este compromiso, tenemos pruebas de integración exhaustivas para todas las funciones de Next.js, incluidas pruebas que replican el desarrollo local.

Cuando una función en Next.js se deprecia y requiere cambios importantes en la base de código, nuestro equipo crea un codemod para ello. Un codemod es una transformación de código automatizada que puede ejecutar en su proyecto para actualizar el código fuente.

Por ejemplo: Lanzamos un codemod para actualizar funciones de flecha y funciones anónimas a funciones con nombre. Esta transformación es necesaria porque, de lo contrario, React Fast Refresh no detecta la función como un componente React válido. De manera similar, las reglas de eslint para hooks de React no detectarían la función como un componente React.

Con Next.js 10, estamos lanzando una nueva herramienta CLI de codemods de Next.js que le permite ejecutar un solo comando para actualizar su aplicación: npx @next/codemod <transform> <path>.

Para obtener más información sobre los codemods, puede consultar la documentación de Codemods de Next.js.

Bloqueo de respaldo (Blocking Fallback) para getStaticPaths

En Next.js 9.3, presentamos getStaticProps y getStaticPaths junto con la capacidad de devolver una propiedad fallback en getStaticPaths. La propiedad fallback permite generar páginas estáticas adicionales sin necesidad de una reconstrucción completa, sirviendo inicialmente un archivo HTML estático que luego se reemplaza por el contenido completamente renderizado en solicitudes posteriores. En los últimos meses, hemos recibido muchos comentarios de empresas que querían un comportamiento similar pero ligeramente diferente: una pre-renderización bloqueante cuando un usuario solicita la página por primera vez. Después de ese renderizado inicial, la página se reutilizaría para solicitudes posteriores.

Con Next.js 10, estamos resolviendo este caso.

Nos complace anunciar el nuevo modo fallback: 'blocking' para getStaticPaths que habilita el comportamiento de bloqueo donde no se envía un respaldo estático al navegador. En su lugar, se espera a la solicitud inicial para la pre-renderización.

pages/posts/[id].js
export function getStaticPaths() {
  return {
    // habilita el modo de bloqueo para el comportamiento de respaldo
    fallback: 'blocking',
  };
}

Para obtener más información sobre el comportamiento de fallback para generar incrementalmente páginas estáticas adicionales, puede consultar la documentación de fallback.

Soporte para redirect y notFound en getStaticProps / getServerSideProps

Desde la introducción de getStaticProps y getServerSideProps, hemos notado casos en los que los usuarios necesitan devolver redirecciones y respuestas 404. Para ayudar a agilizar estos casos, ahora permitimos devolver dos nuevos campos desde getStaticProps y getServerSideProps: notFound y redirect.

Soporte para notFound

Al devolver el campo notFound con true, se devolverá la página 404 predeterminada con un código de estado 404. Esto le permite evitar generar páginas adicionales con SSG y tener que manejar el renderizado de la página 404 manualmente.

pages/posts/[id].js
export function getStaticProps() {
  return {
    // devuelve la página 404 predeterminada con un código de estado 404
    notFound: true,
  };
}

Soporte para redirect

Ahora se pueden devolver redirecciones que contienen el destination y si la redirección debe ser permanente o no, por ejemplo, permanent: true. También se puede devolver un statusCode opcional en lugar del campo permanent para casos en los que necesite usar un estado específico en lugar de los predeterminados.

pages/posts/[id].js
export function getStaticProps() {
  return {
    // devuelve una redirección a una página interna `/another-page`
    redirect: {
      destination: '/another-page',
      permanent: false,
    },
  };
}
pages/posts/[id].js
export function getServerSideProps() {
  return {
    // devuelve una redirección a un dominio externo `example.com`
    redirect: {
      destination: 'https://example.com',
      permanent: false,
    },
  };
}

Conclusión

Nos entusiasma ver el crecimiento continuo en la adopción de Next.js:

  • Hemos tenido más de 1,300 colaboradores independientes, con más de 120 nuevos colaboradores desde el lanzamiento de la versión 9.5
  • En GitHub, el proyecto ha sido marcado con estrella más de 54,800 veces.

Únase a la comunidad de Next.js en GitHub Discussions. Discussions es un espacio comunitario que le permite conectarse con otros usuarios de Next.js y hacer preguntas o compartir su trabajo libremente.

Créditos

Estamos agradecidos con nuestra comunidad, incluyendo todos los comentarios externos y contribuciones que ayudaron a dar forma a esta versión.

Esta versión fue posible gracias a las contribuciones de: @ijjk, @adebiyial, @elliottsj, @saintmalik, @HaNdTriX, @prateekbh, @amirsaeed671, @paambaati, @imagentleman, @gregrickaby, @Janpot, @atcastle, @Kirkhammetz, @remorses, @davidsonsns, @kmkzt, @slawekkolodziej, @Timer, @styfle, @timneutkens, @ykzts, @ashconnell, @orYoffe, @lfades, @justinwhall, @fbaiodias, @ludofischer, @felipeguilhermefs, @gr-qft, @TasukuUno, @YichiZ, @weichienhung, @seosmmbusiness, @HsuTing, @gsimone, @peduarte, @ztanner, @neighborhood999, @chibicode, @merceyz, @opudalo, @lunchboxav, @mohsen1, @akd-io, @justman00, @helloworld, @devknoll, @borekb, @ArthurMaverick, @sakito21, @TrySound, @omBratteng, @svenheden, @hallaji, @kettanaito, @vvo, @m-lautenbach, @jensmeindertsma, @Zeko369, @longlho, @stefanprobst, @laugharn, @sdornan, @daneroo, @mohd-akram, @austingmhuang, @sphilee, @devinekadeni, @Bacher, @nghiepit, @tomasdisk, @leader22, @paulogdm, @284km, @belgattitude, @geritol, @stigkj, @sampoder, @samrobbins85, @Pitasi, @digitalPlayer1125, @timfee, @plug-n-play, @philihp, @leerob, @dylanjha, @Kerumen, @rdimaio, @jorisw, @zerbinidamata, @jamesgeorge007, @Jashnm, y @futantan!