Wiz テックブログ

Wizは、最新のIoTやICTサービスをお客様に届ける「ITの総合商社」です。

Next.jsでのDynamic Importの使い所

こんにちは、フロントエンドエンジニアの髙橋です。

最近社内でNextを採用したプロジェクトが増えつつあるなか、色々な機能に驚き、助けられている日々を過ごしております。 そんな中、今回はDynamic Importの使い所について考えてみたいと思います。

そもそもDynamic Importって??

その名の通り動的なインポートのことです! ES2020の新機能で、Nextでもサポートされています。

書き方としては、Nextが提供しているnext/dynamicからimportして下記のように使用します。

import dynamic from 'next/dynamic'

// 静的なインポート
// import StaticComponent from '../components/hello'

// 動的なインポート
const DynamicComponent = dynamic(() => import('../components/hello'))

function Home() {
  return (
    <div>
      <Header />
      <DynamicComponent />
      <p>HOME PAGE is here!</p>
    </div>
  )
}

export default Home

nextjs.org

どうやって使用する??

そんなDynamic Importですが、さまざまな使い方があると思います。

今回は私がよく使う2つの用途を書いていきます!

パフォーマンス改善に使用する

一つ目の用途はパフォーマンス改善です。

例えば、このようなユーザーの操作によって切り替わる要素があるとします。

 

静的インポートの場合

こちらを静的にImportするとこのように書けば表現できます。

import { useState } from 'react';
import List from '../components/List'
import ListSecondary from '../components/ListSecondary'

const IndexPage = () => {
  const [toggle, setToggle] = useState(true);
  return (
    <Layout title="Home | Next.js + TypeScript Example">
      <h1>Hello Next.js 👋</h1>
      <button onClick={() => setToggle(!toggle)}>
        Toggle Component
      </button>
      {toggle ?  <List /> : <ListSecondary />}
    </Layout>
  )
}

export default IndexPage

listlistSecondaryToggle Componentを押すことで切り替えるようにしています。

早速Light houseのスコアを見てみましょう。

シンプルなページなのに少しパフォーマンスが悪いですね… 原因はListSecondaryは初期画面に表示されないのにロード時に読み込んでしまっているためです。 (わかりやすくするためにListSecondaryはめっちゃ大きくしています…笑) ではこちらを動的にインポートすればどうなるでしょうか。

動的インポート(Dynamic Importの場合)

Dynamic Importの場合、以下のように書きます

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

const AboutPage = () => {
  const [toggle, setToggle] = useState(true);
  return (
    <Layout title="Home | Next.js + TypeScript Example">
      <h1>Hello Next.js 👋</h1>
      <button onClick={() => setToggle(!toggle)}>
        Toggle Component
      </button>
      {toggle ?  <List /> : <ListSecondary />}
    </Layout>
  )
}

挙動を確認してみましょう。

Listは最初から表示されているのに対して、ListSecondaryは最初に切り替わるとき、少しラグがあります。 (一瞬なのでかなり見えづらいですが…) これはToggle Componentを押したときにImportしているため、このような挙動になります。

ではこちらのスコアはどうでしょうか。 f:id:sotq17:20210519170107p:plain

少しスコア上がったことが確認できました!

静的にインポートしたときに比べ、Dynamic Importは初期ロード時に読み込む量を減らすことができるため、サイトスピードの向上に使用することができます。

Dynamic Importを使用することで、比較的簡単にパフォーマンスチューニングすることができます。 初期表示の際に不必要なComponentが多い場合はDynamic Importを検討してみてはいかがでしょうか。  

SSR回避に使用する

もう一つ私がよく使用する用途は、SSR回避の用途です。

Nextを使っているとこんなエラーが出てくる時はないでしょうか?? ReferenceError: alert is not defined

私は気を抜いているとよくこのように怒られてしまいます。。 NextはSSR前提で動いているので、こういったブラウザの機能を使おうとするとエラーが出てしまいます。

ちなみにこういった書き方だと、上記のようなエラーとなります

import React from 'react'

import Alert  from '../../components/Alert'
const AlertPage = () => {
  return (
    <Alert/>
  )
}
export default AlertPage


*Alertはalertの機能を持つReact Componentです。

こういうときにもDynamic Importが役に立ちます!

先程のDynamic Importの書き方に{ssr: false}というオプションを渡してあげるだけで、「このファイルはSSRしない」とNextが判断するので、エラー回避することができます。

先程のソースを変更すると、以下のようになります。

import React from 'react'
import dynamic from 'next/dynamic';

const Alert = dynamic(() => import( '../../components/Alert'),{ssr:false})
const AlertPage = () => {
  return (
    <Alert/>
  )
}
export default AlertPage

これでエラーがなくなるはずです!

参考までにソースが上がったGithubも載せておきます。

github.com

まとめ

今回はNextのDynamic Importの使い方についてご紹介しました。 今回ご紹介した用途は一部の使い方で、もっといろんなことができると思います。 こんな風に使えるよ!ってご意見あれば是非ご教示いただきたいです…!

最後までお読み頂きありがとうございました!

最後に


Wizではエンジニアとして一緒に働く仲間を絶賛募集しております。

ご興味のある方、是非ご覧下さい..!!

careers.012grp.co.jp