Cómo optimizar tu entorno de desarrollo local

Next.js está diseñado para proporcionar una excelente experiencia de desarrollo. A medida que tu aplicación crece, podrías notar tiempos de compilación más lentos durante el desarrollo local. Esta guía te ayudará a identificar y solucionar problemas comunes de rendimiento en tiempo de compilación.

Desarrollo local vs producción

El proceso de desarrollo con next dev es diferente a next build y next start.

next dev compila las rutas de tu aplicación a medida que las abres o navegas a ellas. Esto te permite iniciar el servidor de desarrollo sin esperar a que se compile cada ruta de tu aplicación, lo que es más rápido y usa menos memoria. Ejecutar una compilación de producción aplica otras optimizaciones, como minimizar archivos y crear hashes de contenido, que no son necesarios para el desarrollo local.

Mejorar el rendimiento del desarrollo local

1. Verifica el antivirus de tu computadora

El software antivirus puede ralentizar el acceso a archivos.

Intenta agregar tu carpeta de proyecto a la lista de exclusiones del antivirus. Aunque esto es más común en máquinas Windows, lo recomendamos para cualquier sistema con una herramienta antivirus instalada.

2. Actualiza Next.js y habilita Turbopack

Asegúrate de estar usando la última versión de Next.js. Cada nueva versión suele incluir mejoras de rendimiento.

Turbopack es un nuevo empaquetador integrado en Next.js que puede mejorar el rendimiento local.

npm install next@latest
npm run dev --turbopack

Aprende más sobre Turbopack. Consulta nuestras guías de actualización y codemods para más información.

3. Verifica tus imports

La forma en que importas código puede afectar significativamente el tiempo de compilación y empaquetado. Aprende más sobre optimización de empaquetado de paquetes y explora herramientas como Dependency Cruiser o Madge.

Bibliotecas de iconos

Bibliotecas como @material-ui/icons o react-icons pueden importar miles de iconos, incluso si solo usas unos pocos. Intenta importar solo los iconos que necesites:

// En lugar de esto:
import { Icon1, Icon2 } from 'react-icons/md'

// Haz esto:
import Icon1 from 'react-icons/md/Icon1'
import Icon2 from 'react-icons/md/Icon2'

Bibliotecas como react-icons incluyen muchos conjuntos de iconos diferentes. Elige un conjunto y quédate con él.

Por ejemplo, si tu aplicación usa react-icons e importa todos estos:

  • pi (Phosphor Icons)
  • md (Material Design Icons)
  • tb (tabler-icons)
  • cg (cssgg)

Combinados serán decenas de miles de módulos que el compilador tiene que manejar, incluso si solo usas una importación de cada uno.

Archivos barrel

Los "archivos barrel" son archivos que exportan muchos elementos de otros archivos. Pueden ralentizar las compilaciones porque el compilador tiene que analizarlos para encontrar si hay efectos secundarios en el ámbito del módulo al usar la importación.

Intenta importar directamente desde archivos específicos cuando sea posible. Aprende más sobre archivos barrel y las optimizaciones integradas en Next.js.

Optimiza las importaciones de paquetes

Next.js puede optimizar automáticamente las importaciones para ciertos paquetes. Si usas paquetes que utilizan archivos barrel, agrégalos a tu next.config.js:

module.exports = {
  experimental: {
    optimizePackageImports: ['package-name'],
  },
}

Turbopack analiza automáticamente las importaciones y las optimiza. No requiere esta configuración.

4. Verifica tu configuración de Tailwind CSS

Si usas Tailwind CSS, asegúrate de que esté configurado correctamente.

Un error común es configurar tu array content de manera que incluya node_modules u otros directorios grandes de archivos que no deberían escanearse.

Tailwind CSS versión 3.4.8 o posterior te advertirá sobre configuraciones que podrían ralentizar tu compilación.

  1. En tu tailwind.config.js, sé específico sobre qué archivos escanear:

    module.exports = {
      content: [
        './src/**/*.{js,ts,jsx,tsx}', // Bueno
        // Esto podría ser demasiado amplio
        // Coincidirá con `packages/**/node_modules` también
        // '../../packages/**/*.{js,ts,jsx,tsx}',
      ],
    }
  2. Evita escanear archivos innecesarios:

    module.exports = {
      content: [
        // Mejor - solo escanea la carpeta 'src'
        '../../packages/ui/src/**/*.{js,ts,jsx,tsx}',
      ],
    }

5. Verifica configuraciones personalizadas de webpack

Si has agregado configuraciones personalizadas de webpack, podrían estar ralentizando la compilación.

Considera si realmente las necesitas para el desarrollo local. Opcionalmente, puedes incluirlas solo para compilaciones de producción, o explorar migrar a Turbopack y usar loaders.

6. Optimiza el uso de memoria

Si tu aplicación es muy grande, podría necesitar más memoria.

Aprende más sobre optimización del uso de memoria.

7. Componentes de Servidor y obtención de datos

Los cambios en los Componentes de Servidor hacen que toda la página se vuelva a renderizar localmente para mostrar los nuevos cambios, lo que incluye obtener nuevos datos para el componente.

La opción experimental serverComponentsHmrCache te permite almacenar en caché las respuestas de fetch en Componentes de Servidor a través de refrescos de Hot Module Replacement (HMR) en el desarrollo local. Esto resulta en respuestas más rápidas y costos reducidos para llamadas API facturadas.

Aprende más sobre la opción experimental.

8. Considera el desarrollo local sobre Docker

Si usas Docker para desarrollo en Mac o Windows, podrías experimentar un rendimiento significativamente más lento en comparación con ejecutar Next.js localmente.

El acceso al sistema de archivos de Docker en Mac y Windows puede hacer que Hot Module Replacement (HMR) tome segundos o incluso minutos, mientras que la misma aplicación se ejecuta con HMR rápido cuando se desarrolla localmente.

Esta diferencia de rendimiento se debe a cómo Docker maneja las operaciones del sistema de archivos fuera de entornos Linux. Para la mejor experiencia de desarrollo:

  • Usa desarrollo local (npm run dev o pnpm dev) en lugar de Docker durante el desarrollo
  • Reserva Docker para implementaciones de producción y pruebas de compilaciones de producción
  • Si debes usar Docker para desarrollo, considera usar Docker en una máquina o VM Linux

Aprende más sobre implementación con Docker para uso en producción.

Herramientas para encontrar problemas

Registro detallado de fetch

Usa la opción logging.fetches en tu archivo next.config.js para ver información más detallada sobre lo que sucede durante el desarrollo:

module.exports = {
  logging: {
    fetches: {
      fullUrl: true,
    },
  },
}

Aprende más sobre registro de fetch.

Trazado de Turbopack

El trazado de Turbopack es una herramienta que te ayuda a entender el rendimiento de tu aplicación durante el desarrollo local. Proporciona información detallada sobre el tiempo que toma compilar cada módulo y cómo están relacionados.

  1. Asegúrate de tener la última versión de Next.js instalada.

  2. Genera un archivo de trazado de Turbopack:

    NEXT_TURBOPACK_TRACING=1 npm run dev
  3. Navega por tu aplicación o edita archivos para reproducir el problema.

  4. Detén el servidor de desarrollo de Next.js.

  5. Un archivo llamado trace-turbopack estará disponible en la carpeta .next.

  6. Puedes interpretar el archivo usando next internal trace [ruta-al-archivo]:

    next internal trace .next/trace-turbopack

    En versiones donde trace no está disponible, el comando se llamaba turbo-trace-server:

    next internal turbo-trace-server .next/trace-turbopack
  7. Una vez que el servidor de trazado esté en ejecución, puedes ver el trazado en https://trace.nextjs.org/.

  8. Por defecto, el visor de trazado agregará los tiempos; para ver cada tiempo individual puedes cambiar de "Agregado en orden" a "Intervalos en orden" en la parte superior derecha del visor.

¿Sigues teniendo problemas?

Comparte el archivo de trazado generado en la sección Trazado de Turbopack y compártelo en GitHub Discussions o Discord.