こんにちは、フロントエンドエンジニアの髙橋です。
最近社内で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
どうやって使用する??
そんな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
list
とlistSecondary
をToggle 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しているため、このような挙動になります。
ではこちらのスコアはどうでしょうか。
少しスコア上がったことが確認できました!
静的にインポートしたときに比べ、Dynamic Importは初期ロード時に読み込む量を減らすことができるため、サイトスピードの向上に使用することができます。
Dynamic Importを使用することで、比較的簡単にパフォーマンスチューニングすることができます。 初期表示の際に不必要なComponentが多い場合はDynamic Importを検討してみてはいかがでしょうか。
SSR回避に使用する
もう一つ私がよく使用する用途は、SSR回避の用途です。
Nextを使っているとこんなエラーが出てくる時はないでしょうか??
私は気を抜いているとよくこのように怒られてしまいます。。 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も載せておきます。
まとめ
今回はNextのDynamic Importの使い方についてご紹介しました。 今回ご紹介した用途は一部の使い方で、もっといろんなことができると思います。 こんな風に使えるよ!ってご意見あれば是非ご教示いただきたいです…!
最後までお読み頂きありがとうございました!
最後に
Wizではエンジニアとして一緒に働く仲間を絶賛募集しております。
ご興味のある方、是非ご覧下さい..!!