Lang x Lang

Lazy Loading

Lazy loading は、 Next.js において、最初の loading 性能を向上させるために、 route を render するのに必要な JavaScript の量を減らすのに役立ちます。

それにより、Client Componentsやインポートされたライブラリの loading を延期し、それらが必要となったときにだけ client バンドルに含めることが可能になります。例えば、ユーザーがそれを開くためにクリックするまでモーダルの loading を延期することができるでしょう。

あなたが Next.js で lazy loading を実装できる 2 つの方法があります:

  1. Dynamic Importsnext/dynamicで使用する
  2. React.lazy() Suspense と共に使用する

default では、Server Components は自動的に code split され、streaming を使用して UI の一部を server から client に順次送信できます。Lazy loading は、Client Components に適用されます。

next/dynamic

next/dynamicReact.lazy() Suspense の組み合わせです。これはapppagesディレクトリで同じように動作し、段階的な移行を可能にします。

Examples

Client Components のインポート

app/page.js
'use client'

import { useState } from 'react'
import dynamic from 'next/dynamic'

// Client Components:
const ComponentA = dynamic(() => import('../components/A'))
const ComponentB = dynamic(() => import('../components/B'))
const ComponentC = dynamic(() => import('../components/C'), { ssr: false })

export default function ClientComponentExample() {
  const [showMore, setShowMore] = useState(false)

  return (
    <div>
      {/* Load immediately, but in a separate client bundle */}
      <ComponentA />

      {/* Load on demand, only when/if the condition is met */}
      {showMore && <ComponentB />}
      <button onClick={() => setShowMore(!showMore)}>Toggle</button>

      {/* Load only on the client side */}
      <ComponentC />
    </div>
  )
}

SSR をスキップ

React.lazy() と Suspense を使用すると、 Client Components は default により、事前に描画( SSR )されます。

もし Client Component のプレレンダリングを無効にしたい場合、ssrオプションをfalseに設定して使用することができます:

const ComponentC = dynamic(() => import("../components/C"), { ssr: false });

Server Components のインポート

Server Component を動的に import すると、Server Component の children である Client Components のみが遅延ロードされます - Server Component 自体はロードされません。

app/page.js
import dynamic from 'next/dynamic'

// Server Component:
const ServerComponent = dynamic(() => import('../components/ServerComponent'))

export default function ServerComponentExample() {
  return (
    <div>
      <ServerComponent />
    </div>
  )
}

Loading 外部ライブラリの読み込み

外部ライブラリは、import() 関数を使用して必要に応じてロードすることができます。この例では、曖昧検索のための外部の library fuse.jsを使用しています。モジュールは、ユーザーが検索入力を入力した後でのみ client 上にロードされます。

app/page.js
'use client'

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
          // Dynamically load 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>
  )
}

カスタム loading component の追加

app/page.js
import dynamic from 'next/dynamic'

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

export default function Page() {
  return (
    <div>
      {/* The loading component will be rendered while  <WithCustomLoading/> is loading */}
      <WithCustomLoading />
    </div>
  )
}

名前付き export のインポート

動的に import を実行し、名前付きの export を取り込むには、import() 関数によって返される Promise からそれを返すことができます。

components/hello.js
'use client'

export function Hello() {
  return <p>Hello!</p>
}
app/page.js
import dynamic from 'next/dynamic'

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

当社サイトでは、Cookie を使用しています。各規約をご確認の上ご利用ください:
Cookie Policy, Privacy Policy および Terms of Use