next/imageについての機能と型についてメモ

Next.js10から新たに搭載された機能👇「next/image」
https://nextjs.org/blog/next-10

めちゃくちゃ便利ですよね。
ただ、SGでレンダリングする時にちょっと躓いたので、ここにメモ。

imageコンポーネントは画像の最適化を自動的にしてくれる

imageコンポーネントは、簡単に説明すると
「自動的に”画像をいい感じにして”表示してくれる」機能です。

ページの読み込み速度は早ければ早いほど、
ユーザビリティは向上します。

Next.jsの公式ドキュメントによると、
Web ページの総バイト数の 50% を画像が占めているそう!

これらが全てバイト数の大きい激重な画像なら、
当然読み込み速度も落ちます。

アクセスされたデバイスに応じて
画像を出し分けることも可能ですが、
全てを管理するのは大変です。

また、webPに対応したブラウザにはwebPで表示させた方が
更に読み込み速度を早くすることができます。

こんな感じでデバイスに合わせた画像を用意するのも大変、
管理も大変、設定も大変。

でも、Next.jsのimageコンポーネントを使えば
それらを自動的にいい感じにしてくれるんです。
素敵!

何枚も画像を用意したり、設定しなくてもいいんです💓

ちなみに、ユーザーがwebP対応のブラウザを使用していたら、
自動的にwebP形式の画像を用意して表示してくれます。すごい!

注意:SGでは使えない

こんな感じでとても便利そうなimageコンポーネントですが、
実はSGでレンダリングする時には使えません。
buildの際にエラーが出てしまいます…

設定を変更すればエラーは消えます。
しかし、imageコンポーネントの恩恵は受けられません😭
(ただのimgタグと同じ挙動になります。)

SGでレンダリングする時にエラーが出ないように設定する

SGでレンダリングするならimageコンポーネントを使う理由は無いですが、
念のためimageコンポーネントを使ってSGでレンダリングする時に
エラーが出ないようにする設定方法をここにメモしておきます。

①next.config.jsonに記述を追加

//下記の記述を追加する

  images: {
    loader: "custom",
  },
//全体像はこんな感じ

/** @type {import('next').NextConfig} */

const nextConfig = {
  reactStrictMode: true,
  swcMinify: true,
  images: {
    loader: "custom",
  },
};

module.exports = nextConfig;

②Imageコンポーネントにloader属性を追加

// Before
// create-next-app した時に、自動的に挿入されるコードを例に説明

<Image 
 src="/vercel.svg"
 alt="Vercel Logo"
 width={72}
 height={16}
/>
// After
// lorder属性を記述し、受け取ったsrcをそのまま返す関数を記述
// ただ、これではエラーが出ます!理由は後述

<Image 
 loader={(src) => src}
 src="/vercel.svg"
 alt="Vercel Logo"
 width={72}
 height={16}
/>

lorderにはどんな型が渡ってくるのか確認しよう!

上記のコードではエラーがでます。
理由は、受け取った引数(src)を分割代入していないためです。
(私はここで詰まって時間を浪費した…)

どんな型のデータが渡ってくるのでしょうか?
確認してみましょう!

先ほど記述したlorder属性のlorder部分をctrl + クリック🖱️

ImageLoaderが定義されている

ImageLoaderってなんだろう?ということで、ctrl + クリック🖱️

ImageLoaderには、ImageLoaderPropsが定義されている。

ImageLoaderPropsはsrc、width、qualityの3つのプロパティが定義されていますね。
型はstringまたはnumber。
ふむふむ、こんなデータが渡ってくるのか…🧐

ということで、今回はsrcのみ使用したいので
渡ってきたデータを分割代入し、srcだけ取り出して使用しましょう!

// loader={({src}) => src}を追加

<Image 
 loader={({src}) => src}
 src="/vercel.svg"
 alt="Vercel Logo"
 width={72}
 height={16}
/>

これでSGでレンダリングした時もエラーは出ません。
でも、imageコンポーネントの恩恵は受けられないので注意です…

それでは!

コメント

タイトルとURLをコピーしました