Introducción/Guías/Carga diferida

Cómo cargar de forma diferida componentes de cliente y bibliotecas

La carga diferida (Lazy loading) en Next.js ayuda a mejorar el rendimiento de carga inicial de una aplicación al reducir la cantidad de JavaScript necesaria para renderizar una ruta.

Te permite diferir la carga de Componentes de Cliente y bibliotecas importadas, incluyéndolas en el paquete del cliente solo cuando son necesarias. Por ejemplo, podrías querer diferir la carga de un modal hasta que un usuario haga clic para abrirlo.

Hay dos formas de implementar la carga diferida en Next.js:

  1. Usando Importaciones Dinámicas con next/dynamic
  2. Usando React.lazy() con Suspense

Por defecto, los Componentes de Servidor se dividen automáticamente en código (code splitting), y puedes usar streaming para enviar progresivamente partes de la interfaz de usuario desde el servidor al cliente. La carga diferida aplica a Componentes de Cliente.

next/dynamic

next/dynamic es una combinación de React.lazy() y Suspense. Se comporta de la misma manera en los directorios app y pages para permitir una migración incremental.

Ejemplos

Al usar next/dynamic, el componente de encabezado no se incluirá en el paquete inicial de JavaScript de la página. La página renderizará primero el fallback de Suspense, seguido del componente Header cuando se resuelva el límite de Suspense.

import dynamic from 'next/dynamic'

const DynamicHeader = dynamic(() => import('../components/header'), {
  loading: () => <p>Loading...</p>,
})

export default function Home() {
  return <DynamicHeader />
}

Bueno saber: En import('ruta/al/componente'), la ruta debe escribirse explícitamente. No puede ser una cadena de plantilla ni una variable. Además, el import() debe estar dentro de la llamada dynamic() para que Next.js pueda emparejar los paquetes de webpack / IDs de módulo con la llamada dynamic() específica y precargarlos antes del renderizado. dynamic() no se puede usar dentro del renderizado de React ya que debe marcarse en el nivel superior del módulo para que funcione la precarga, similar a React.lazy.

Con exportaciones con nombre

Para importar dinámicamente una exportación con nombre, puedes devolverla desde la Promesa retornada por import():

components/hello.js
export function Hello() {
  return <p>Hello!</p>
}

// pages/index.js
import dynamic from 'next/dynamic'

const DynamicComponent = dynamic(() =>
  import('../components/hello').then((mod) => mod.Hello)
)

Sin SSR

Para cargar dinámicamente un componente en el lado del cliente, puedes usar la opción ssr para desactivar el renderizado en el servidor. Esto es útil si una dependencia externa o componente depende de APIs del navegador como window.

'use client'

import dynamic from 'next/dynamic'

const DynamicHeader = dynamic(() => import('../components/header'), {
  ssr: false,
})

Con bibliotecas externas

Este ejemplo usa la biblioteca externa fuse.js para búsqueda difusa. El módulo solo se carga en el navegador después de que el usuario escribe en el campo de búsqueda.

import { useState } from 'react'

const names = ['Tim', 'Joe', 'Bel', 'Lee']

export default function Page() {
  const [results, setResults] = useState()

  return (
    <div>
      <input
        type="text"
        placeholder="Search"
        onChange={async (e) => {
          const { value } = e.currentTarget
          // Carga dinámicamente fuse.js
          const Fuse = (await import('fuse.js')).default
          const fuse = new Fuse(names)

          setResults(fuse.search(value))
        }}
      />
      <pre>Results: {JSON.stringify(results, null, 2)}</pre>
    </div>
  )
}

On this page