こんにちは。
Next.jsで個人ブログを作成する際に何度か画像周りで詰まるケースがありました。また、その度にLCPや画像最適化といった文言に遭遇しました。
当記事ではNext.jsの画像に関連するLCP画像最適化について調べた内容を備忘録代わりに記載したいと思います。
当記事では英文の和訳としてGoogle翻訳を利用しています。
前提:Next.jsでの画像表示周りの警告文
私がNext.jsで画像関連の実装をしていた際に2種類のケースで警告に遭遇しました。
それぞれの内容を見ていきます。
①Imageコンポーネントではなくimgタグを使用した場合
Next.jsでは画像の読み込みではnext/image の <Image /> コンポーネントが推奨されています。
それに気づかず<img>タグを使ったところ以下の警告が出ました。
Using
<img>could result in slower LCP and higher bandwidth. Consider using<Image />fromnext/imageor a custom image loader to automatically optimize images. This may incur additional usage or cost from your provider.
See: https://nextjs.org/docs/messages/no-img-element
<img>を使用すると、LCP(Largest Contentful Paint)の遅延や帯域幅の増大を招く可能性があります。画像を自動的に最適化するために、next/imageの<Image />コンポーネントやカスタム画像ローダーの利用を検討してください。なお、これに伴い、利用しているプロバイダーから追加の利用料やコストを請求される場合があります。
詳細はこちら:https://nextjs.org/docs/messages/no-img-element
警告文の中で出てきたドキュメント
②大きめのサイズの画像を使用した場合
元画像のサイズが1920×1080の画像をページ内で使ったところ以下の警告文が出ました。
[browser] Image with src "(サイト内で使用した画像のパス)" was detected as the Largest Contentful Paint (LCP). Please add the
loading="eager"property if this image is above the fold.
Read more: https://nextjs.org/docs/app/api-reference/components/image#loading
[browser] srcが「(サイト内で使用した画像のパス)」である画像が、Largest Contentful Paint (LCP) として検出されました。この画像がファーストビュー(above the fold)にある場合は、
loading="eager"プロパティを追加してください。
詳細はこちら: https://nextjs.org/docs/app/api-reference/components/image#loading
警告文の中で出てくるドキュメント
いずれも「LCP」というフレーズが出てきました。
次にLCPについて調べてみます。
LCPとは
LCPは、GoogleのWebページ品質改善ツールである「Lighthouse」のパフォーマンス指標の1つであり、Webページ内で最大のコンテンツがビューポートに表示されるまでの時間を示したものです。
端的に言うと画像の読み込み速度といえそうです。
参考:chrome for developersによるLCP、Lighthouseの概要
主な対策例として
-
ファーストビュー以外の画像は遅延読み込みする
- 初期読み込み時には見せる必要がないため、表示しない時には読み込まないことでリソースを節約する
- 遅延読み込みのために使う属性が
loading="lazy"
-
ファーストビューは逆に遅延読み込みさせず初期状態で読み込むようにさせる
-
loading="eager"を指定すると遅延読み込みをオフにできる
-
-
適切な画像フォーマットを活用する
- 例:webpを使うとpngやjpgと比較して約25%ほどサイズを小さくできる
などがあります。
Googleの調査結果としてページ読み込み時間が1秒→3秒になると直帰率が32%上昇するというものもあり、読み込み時間と同様にLCPはユーザーの体験に関わり、サイトを閲覧してくれるかに関わる指標です。
Next.jsで実装されている画像最適化
Next.jsでは'next/image'を使ったImageコンポーネントが、画像最適化の手法として推奨されています。
import Image from 'next/image'
export default function Page() {
return (
<Image
src="/profile.png"
width={500}
height={500}
alt="Picture of the author"
/>
)
}
公式ドキュメントを参考に、具体的にどのような画像最適化を行っているか見てみます。
- widthとheightの指定:デフォルトのアスペクト比を画像のwidthとheightの値に基づくことで、画像のレイアウトシフト(ページ読み込み時のレイアウト変化)を防ぐ
- webp画像での出力:デフォルト設定では圧縮度の高いwebpで画像を出力する
-
画質の調整:画像の使用箇所に合わせて画質を調整できる
-
quality属性を使用
-
- 事前に画像を読み込む際のpreload属性
-
loading属性の設定-
lazy:遅延読み込み。基本はこちら -
eager:即座に読み込み。初期表示で読み込みたい画像のみ
-
といった方法がとられています。
width/heightの指定はほぼ毎回使う箇所で、webp方式への変換は自動で行われるため、Imageコンポーネントでは画像を最適化しやすい仕組みが揃っていると言えそうです。
最後に
ここまで読んで下さりありがとうございます。
LCP周りについて知見を深めることで、なぜNext.jsで「画像を最適化」できているかについての理解も深まったように感じました。
参考資料