[Next.js] next/image で画像の遅延読み込み中に、サムネイルをぼかさずに表示する方法
アルダグラムでソフトウェアエンジニアとして活動している松田です。
Next.jsでは、next/image
(または Next.js 12 以前の next/legacy/image
) コンポーネントを使用して効率的に画像を表示できます。
このコンポーネントは標準の <img>
タグを拡張し、遅延読み込みや画像最適化といった機能を提供します。
機能の一つに、メイン画像が読み込まれるまでの間、代替画像(サムネイル)をぼかして表示するプレースホルダーがあります。
しかし、ユースケースによっては、このぼかし効果を適用したくない場合もあるでしょう。
本稿では、next/image
および next/legacy/image
コンポーネントで、画像の遅延読み込み中にサムネイルをぼかさずに表示する方法を解説します。
手法
早速、実現手法について、簡潔に述べます。
next/image
での実装例
- サムネイル画像の
Data URL
を用意 -
priority
属性をfalse
に設定し、遅延読み込みを有効化 -
placeholder
属性にサムネイル画像のData URL
を指定
import Image from 'next/image'
import { FC } from 'react'
import styles from 'path/to/your/styles.module.css'
const SandboxComponent: FC = () => {
// ...
return (
<Image
src="/path/to/original-image.jpg" // オリジナル画像のパス
priority={false} // 遅延読み込みを有効にする
placeholder="data:image/png;base64,******..." // サムネイル画像のdata URL
className={styles.nextImage}
{...otherProps}
/>
)
}
next/legacy/image
での実装例
next/image
でも利用可能ですが、こちらの実装ではスタイルを上書きしているので、前述の実装手法をお勧めします。
- サムネイル画像の
Data URL
を用意 -
priority
属性をfalse
に設定し、遅延読み込みを有効化 -
placeholder
属性をblur
に設定し、blurDataURL
属性にサムネイル画像のパスを指定 - CSSで
filter: none !important
を指定し、ぼかしを無効化
import Image from 'next/image'
import { FC } from 'react'
import styles from 'path/to/your/styles.module.css'
const SandboxComponent: FC = () => {
// ...
return (
<Image
src="/path/to/original-image.jpg" // オリジナル画像のパス
priority={false} // 遅延読み込みを有効にする
placeholder="blur" // プレースホホルダー設定 (blur or empty)
blurDataURL="/path/to-thumbnail-image.jpg" // サムネイル画像のパス
className={styles.nextImage}
{...otherProps}
/>
)
}
/* styles.module.css */
/**
* img タグを明示的に指定することで、
* next/image, next/legacy/image
* どちらのコンポーネントでも適用される
*/
.nextImage img {
filter: none !important; /* ぼかしを無効化 */
/* ... */
}
解説
next/image
コンポーネントの関連仕様と上記実装例について、もう少し詳しく解説します。
next/image
と next/legacy/image
Next.js 13 で next/image
コンポーネントは大幅に刷新されました。従来の next/image
(Next.js 12 以前) は next/legacy/image
として引き続き利用可能です。
バージョンアップ時などに next/image
関連で予期せぬ表示崩れや不具合が発生した場合は、一時的に next/legacy/image
に切り替えて対応するのも一つの手です。
priority
属性
画像の読み込み優先度を指定する真偽値の属性です。
A boolean that indicates if the image should be preloaded.
defaultで false
ですので、明示的な指定は必須ではありません。
ただ、これが true
の場合、画像は優先的にpreloadされ、その場合、遅延読み込みが無効化されます。
したがって、今回のようなユースケースでは明示的に false
にしておくのが無難です。
placeholder
属性
メイン画像の読み込み中に表示されるプレースホルダーの種類を指定します。
-
empty
: 何も表示しない(画像読み込み完了まで空白) -
blur
:blurDataURL
と併用し、ぼかした画像をプレースホルダーとして使用 -
data:image/...
(Next.js 13.4.14以降のnext/image
でサポート): 指定された Data URL を直接プレースホルダーとして使用
留意点として、 next/legacy/image
では、 data:image/...
の直接指定がサポートされていません。
v13.4.14 placeholder prop support for data:/image…
したがって、Data URLを利用する場合は、 blur
指定の上で blurDataURL
属性にて指定する必要があります。
blurDataURL
属性
placeholder="blur"
が指定された場合に、プレースホルダーとして使用される画像の Data URL を指定します。
この属性に指定した画像は、コンポーネント内部で filter: blur(...)
スタイルが自動適用され、ぼかして表示されます。
next/legacy/image
の実装例で示したのは、この自動適用されるスタイルを CSS で filter: none !important
によって上書きしてぼかしを無効化する、という手法になります。
まとめ
本稿では、next/image
および next/legacy/image
コンポーネントを使用して、画像の遅延読み込み中にサムネイル(プレースホルダー画像)をぼかさずに表示する方法を解説しました。
-
next/image
(v13以降):placeholder
に直接 Data URL を指定するのが最も簡単です。 -
next/legacy/image
:placeholder="blur"
とblurDataURL
を使い、CSS でぼかしを無効化します。
画像の読み込み戦略は、UX向上において重要です。
表示するコンテンツやデザインの要件に応じて最適な手法を選択できるよう、引き出しは多いに越したことはありません。
また、日進月歩のフロントエンド技術の情報を取り扱う際は、情報の信頼性はもとより、情報の鮮度や対象バージョンにも気を配る必要があります。
Next.js のバージョンアップの過渡期にこのような実装に取り組んだことで、改めてその重要性を実感しました。
もっとアルダグラムのエンジニア組織を知りたい人は、ぜひ下記の情報もチェックしてみてください!

株式会社アルダグラムのTech Blogです。 世界中のノンデスクワーク業界における現場の生産性アップを実現する現場DXサービス「KANNA」を開発しています。 採用情報はこちら: herp.careers/v1/aldagram0508/
Discussion