BLOGS
- TamaTの開発事情 -
Next.js Imageを使っているのにスマホでクラッシュした話

2026.01.30
課題解決
はじめに
ポートフォリオサイトを公開した直後、自分のiPhoneで動作確認をしていたときのことです。
スクロールしていると、突然ページがトップに戻り、最終的に「問題が繰り返し起きました」というメッセージとともにクラッシュ。
PCでは問題なく動くのに、なぜ?
調べてみると、iPhoneのSafariでは発生しない。Chromeでだけ落ちる。
原因は、Next.js Imageの最適化タイミングにありました。
環境
- Next.js 14(App Router)
- microCMS(画像ホスティング)
- 無限スクロールでイラストを表示するギャラリーページ
症状
- スクロールして画像を読み込んでいくと、急にページトップに戻る
- それが勝手に繰り返される
- 最終的にクラッシュ
- PCでは発生しない
- iPhoneのSafariでは発生しない
- iPhoneのChromeでのみ発生
原因:Next.js Imageの「最適化」の誤解
画像の表示には、Next.jsのImageコンポーネントを使っていました。
<Image
src={illust.image.url} // microCMSから取得した画像URL
alt={illust.title}
fill
sizes="(max-width: 768px) 100vw, 33vw"
/>Next.js Imageは画像を最適化してくれる。だから大丈夫だろう、と思っていました。
ところが、元画像のサイズは4000×4000px。これが問題でした。
最適化のタイミング
Next.js Imageの最適化は、表示時に行われます。つまり、こういう流れです:
[元画像: 4000x4000px, 5MB]
↓ ダウンロード ← ここでメモリ圧迫
[ブラウザのメモリに展開: 約64MB]
↓ Next.jsが最適化
[表示: 600x600px]ダウンロード時点では、元の巨大な画像がそのままブラウザに読み込まれているのです。
4000×4000pxの画像は、メモリ上で約64MB(4000×4000×4バイト)を使用します。
これが無限スクロールで次々と読み込まれたら...そりゃ落ちますよね。
なぜiPhoneのChromeだけ?
iOSのChromeは内部的にはSafariと同じWebKitエンジンを使っています。ただし:
- Chromeアプリ自体のUIや追加機能でメモリを消費している
- 結果として、Webコンテンツに割り当てられるメモリがSafariより少ない
Safariはギリギリ耐えていたけど、Chromeは限界を超えていた、というわけです。
解決策:サーバー側でリサイズしてから配信する
Next.js Imageに頼るだけでは不十分。ダウンロード時点で小さくする必要があります。
microCMSの画像APIは、URLパラメータでリサイズを指定できます。
<Image
src={`${illust.image.url}?w=600&q=80`} // サイズと品質を指定
alt={illust.title}
fill
sizes="(max-width: 768px) 100vw, 33vw"
/>これで、配信フローはこうなります:
[元画像: 4000x4000px, 5MB]
↓ microCMSサーバーでリサイズ
[配信: 600x600px, 約100KB]
↓ ダウンロード(軽量!)
[ブラウザのメモリに展開: 約1.4MB]64MB → 1.4MB。約98%削減です。
クラッシュしなくなりました。
まとめ
- Next.js Imageは万能ではない
- 最適化は「表示時」に行われる
- ダウンロード時点では元画像サイズのまま
- 画像最適化は「配信時」から考える
- microCMS、Cloudinary、imgixなど、大抵のCDNはURLパラメータでリサイズできる
- サーバー側で小さくしてから配信するのが正解
- 無限スクロールは特にメモリ管理が重要
- 際限なくコンテンツが増えるUIは、リソース消費に気を配る
- PCで動くからといってスマホで動くとは限らない
- メモリ容量が全然違う
- 特にiPhoneのChromeは厳しい
参考
- microCMS 画像API: https://document.microcms.io/image-api/introduction
- Next.js Image Optimization: https://nextjs.org/docs/app/building-your-application/optimizing/images
