0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【備忘録】ブラウザストレージのユースケース

Last updated at Posted at 2025-10-25

フロント実装で「ちょっとデータを置いておきたい」場面、よくありますよね。この記事は Web Storage(localStorage / sessionStorage)IndexedDB を、設計の観点からまとめた備忘録です。初学者の方でも読めるよう、決め方・落とし穴・最小コードをギュッと詰めました。


概要

業務のwebアプリケーション開発のなかで、クライアントサイドでの一時データ保存をすることになりました。
localStorageは使ったことがありますが、ブラウザストレージについて理解が浅い状態のため、備忘録としてこれを残します。


想定読者

  • フロントエンド言語の初学者
  • WebWorker,ブラウザストレージ(LocalStorage, IndexedDB)の初学者
  • ブラウザストレージのことを改めて確認したい開発者

ざっくり違い

項目 localStorage sessionStorage IndexedDB
データ型 文字列のみ(JSONで自前変換) 文字列のみ 構造化オブジェクト(Date, Blob, ArrayBuffer など)
スコープ 同一オリジンで共有(全タブ) 同一タブ/ウィンドウのみ 同一オリジン。DB→オブジェクトストア単位
ライフサイクル 明示削除まで(容量圧迫時はブラウザが蒸発し得る) タブ/ウィンドウを閉じるまで 半恒久(容量とストレージポリシー依存)
API 特性 同期(メインスレッドをブロック) 同期 非同期(Promise/イベント、トランザクション)
容量目安 数 MB 程度 数 MB 程度 数十〜数百 MB(実装/空き容量/許可に依存)
検索性 キーのみ キーのみ インデックス/レンジ/カーソル検索
Worker から 直接不可 直接不可 (Web Worker / Service Worker から)
代表イベント storage(他タブ通知) なし upgradeneeded など

補足: プライベートブラウジングでは容量や永続性が制限される場合がある


ざっくり使い分け

[保存したいデータは小さくて文字列だけ?]
      ├─ はい → [タブを跨いで共有したい?]
      │         ├─ はい → localStorage
      │         └─ いいえ → sessionStorage
      └─ いいえ → [大容量/複雑検索/バイナリ/オフライン要件?]
                ├─ はい → IndexedDB
                └─ いいえ → 小規模でも将来拡張を見込むなら IndexedDB、
                            そうでなければ localStorage で十分

最小コード例

localStorage

// 保存
localStorage.setItem('prefs', JSON.stringify({ theme: 'dark' }));
// 取得
const prefs = JSON.parse(localStorage.getItem('prefs') ?? '{}');

sessionStorage

sessionStorage.setItem('flowStep', 'shipping');
const step = sessionStorage.getItem('flowStep');

IndexedDB(素のAPI最短)

const openReq = indexedDB.open('app-db', 1);
openReq.onupgradeneeded = () => {
  const db = openReq.result;
  const store = db.createObjectStore('notes', { keyPath: 'id', autoIncrement: true });
  store.createIndex('byUpdatedAt', 'updatedAt');
};
openReq.onsuccess = () => {
  const db = openReq.result;
  const tx = db.transaction('notes', 'readwrite');
  const store = tx.objectStore('notes');
  store.put({ title: 'hello', updatedAt: Date.now() });
  tx.oncomplete = () => db.close();
};

IndexedDB(idb ラッパー)

import { openDB } from 'idb';

const db = await openDB('app-db', 1, {
  upgrade(db) {
    const store = db.createObjectStore('notes', { keyPath: 'id', autoIncrement: true });
    store.createIndex('byUpdatedAt', 'updatedAt');
  },
});

await db.put('notes', { title: 'hello', updatedAt: Date.now() });
const latest = await db.getAllFromIndex('notes', 'byUpdatedAt');

誤りや補足があればコメントでぜひ教えてください。改善していきます!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?