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ではエンジニアとして一緒に働く仲間を絶賛募集しております。

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

【フロントエンドエンジニア】 場所にとらわれず自社メディア成長に貢献したいフロントエンドエンジニア募集! - 株式会社WizのWebエンジニアの求人 - Wantedly

【バックエンドエンジニア】 勤務地自宅を叶える!バックエンドエンジニアとして事業を成長させたい方募集 - 株式会社WizのWebエンジニアの求人 - Wantedly