紡Book の勉強ノートに戻る
開発記録2026.06.18

同じ写真を2回取りに行ってた — home で取ったのを sessionStorage で渡す

Next.jsパフォーマンス紡Book

綴Photo の、写真 → 言葉を付ける画面で、同じデータを2回取りに行っていたのを1回にしたメモ。勉強のため。

home で「次に意味づけする写真」を表示して、そこから add-meaning(写真に言葉を付ける画面)へ移ります。この導線で、同じ写真を2回 fetch していたことに気づいた。

2回取りに行っていた

流れはこうだった。

正本はサーバ DB の photos_photo。画面メモリは保存しない。サーバ DB photos_photo閉じても残る。同じ行が2回読まれる。home の画面メモリ1回目 /api/photos/next/次の写真を表示する遷移で消える。保存しない。add-meaning の画面メモリ2回目 /api/photos/id/同じ写真を表示する開いている間だけ。保存しない。遷移。渡す場所は無い。ページは独立。

表示は正しく出るので気づきにくいです。

この sessionStorage で受け渡す形は AI と詰めたが、「home 側で先に取っておいて、ID が一致したときだけ拾う」という設計の線引きは自分で決めている。

home で取ったものを持って移動する

コピーはタブの sessionStorage。正本はサーバ DB の photos_photo。サーバ DBphotos_photo/api/photos/next//api/photos/id/閉じても残る書くsessionStorageprefetchedAddMeaningPhotoタブ単位の一時コピーサーバに送られないタブを閉じると消える読む画面メモリadd-meaning の表示開いている間だけ保存しない一致しなければサーバへhome が /api/photos/next/ で1回取り、sessionStorage に書く。ID が一致すればそれを使う。一致しない・無ければサーバ DB から取る。ID 判定は交差で、置き場所ではない。
ts
// add-meaning 側: まず手持ちを見て、無ければ取りに行く
// ※説明用に簡略化。実コードのフィールド名は .id
const cached = sessionStorage.getItem("prefetchedAddMeaningPhoto"); // 保管場所から取り出す(なければ null)
const photo =
  cached && JSON.parse(cached).id === photoId  // 文字列→データに戻して ID を確認
    ? JSON.parse(cached)                     // home で取ったのをそのまま使う
    : await fetch_AddMeaningPhotoById(photoId); // 一致しない時だけ取りに行く

「ID が一致すれば」を挟んでいるのが要で、別の写真を開いたときは手持ちを捨ててちゃんと取りに行きます。手持ちを盲信しません。

保管場所 いつ消えるか サーバーに送られるか 向いている用途
sessionStorage タブを閉じると消える(更新では残る) 送られない この遷移のあいだだけ持っておきたい一時データ
localStorage 明示的に消すまで残る 送られない ログイン状態など長期間保持したいデータ
Cookie 有効期限まで残る(設定次第) リクエストのたびに送られる サーバーと共有したい情報(セッションIDなど)

タブをまたぐと消える前提なので、これは「絶対に残るキャッシュ」ではなく「遷移のあいだだけ手で持っていく」くらいの軽い仕組み。消えても add-meaning が API を叩くだけで、壊れはしません。

画面をまたぐと取得済みデータが消えるのは、各ページが独立して動く Web の構造上自然なことで、気をつけないと同じ API を複数箇所から叩きがちになります。「どこで取ったものを、どこで引き継ぐか」を意識するだけで、こういう二重フェッチは事前に気づけるようになります。


この記事は2026年6月時点の自分の理解で書いています。仕様や認識が変わってる可能性があります。