ブラウザでデータを残す6つの方法。それぞれの特徴と使い分け
Webアプリを作っていると、データを保存したい場面がよくあります。設定を覚えさせたい、入力途中の内容を復元したい、大きなファイルを扱いたい。でも、ブラウザには保存方法がいくつもあって、どれを使えばいいのか迷います。
この記事では、ブラウザでデータを保存する6つの方法を実際に試してみました。それぞれの特徴、容量、使いどころを整理しています。実際に動かせるデモも用意したので、手を動かしながら理解できます。
作ったもの
6つの保存方法を並べて、それぞれ保存・読み込み・削除を試せるページを作りました。実際に触ってみると、それぞれの違いが体感できます。
なぜ6つも方法があるのか
ブラウザでデータを保存する方法が複数あるのは、それぞれに役割が違うからです。小さな設定値ならCookieで十分。大きなデータならIndexedDB。ファイルとして保存したいならDownload API。用途に応じて選ぶ必要があります。
最初は「全部localStorageでいいじゃん」と思っていました。でも、容量制限に引っかかったり、オブジェクトをそのまま保存できなかったり、タブを閉じても残したいのに消えたり。そんな経験を重ねて、それぞれの特徴を理解するようになりました。
1. localStorage:シンプルな永続保存
localStorageは、ブラウザを閉じてもデータが残る保存方法です。約5〜10MBまで保存でき、文字列として保存します。同じオリジン(ドメイン)内で共有されるので、別のページからも同じデータにアクセスできます。
使い方は簡単です。setItemで保存、getItemで読み込み、removeItemで削除。これだけです。
// 保存
localStorage.setItem('testData', '保存したい文字列');
// 読み込み
const value = localStorage.getItem('testData');
// 削除
localStorage.removeItem('testData');
オブジェクトを保存する場合は、JSONに変換する必要があります。最初はこれが分からなくて、オブジェクトをそのまま保存しようとしてエラーになりました。
// オブジェクトを保存する場合
const data = { name: 'テスト', value: 123 };
localStorage.setItem('data', JSON.stringify(data));
// 読み込む場合
const loaded = JSON.parse(localStorage.getItem('data'));
実際に試してみると、保存と読み込みが即座に完了します。非同期処理は不要で、同期的に動作します。ただし、大きなデータを保存すると、ページの読み込みが少し重くなる可能性があります。
2. sessionStorage:タブごとの一時保存
sessionStorageは、localStorageとほぼ同じですが、タブを閉じるとデータが消えます。容量も約5〜10MBで、文字列として保存します。タブごとに独立しているので、同じサイトを複数のタブで開いても、それぞれ別のデータとして扱われます。
使い方はlocalStorageと同じです。setItem、getItem、removeItemを使います。
// 保存
sessionStorage.setItem('testData', '一時的なデータ');
// 読み込み
const value = sessionStorage.getItem('testData');
// 削除
sessionStorage.removeItem('testData');
タブを閉じると自動で消えるので、一時的なデータには便利です。例えば、フォーム入力途中の内容を保存しておいて、誤ってページを離れそうになった時に警告を出す。そんな用途に使えます。
実際に試してみると、タブを閉じて再度開くと、データが消えていることが確認できます。逆に、同じタブ内でページをリロードしても、データは残ります。
3. Cookie:小容量でサーバーに送信される
Cookieは、約4KBという小さな容量しか保存できませんが、サーバーに自動で送信される特徴があります。有効期限を設定でき、期限が来ると自動で削除されます。HTTPリクエストに含まれるので、サーバー側でもデータを読み取れます。
使い方は少し複雑です。document.cookieに文字列として設定します。
// 保存(7日間有効)
function setCookie(name, value, days) {
const date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
const expires = "; expires=" + date.toUTCString();
document.cookie = name + "=" + (value || "") + expires + "; path=/";
}
// 読み込み
function getCookie(name) {
const nameEQ = name + "=";
const ca = document.cookie.split(';');
for (let i = 0; i < ca.length; i++) {
let c = ca[i];
while (c.charAt(0) == ' ') c = c.substring(1, c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
}
return null;
}
4KBという制限は意外と厳しく、JSONに変換したオブジェクトを保存しようとすると、すぐに容量オーバーになりました。小さな設定値や、ユーザーIDのような軽量なデータに使うのが適しています。
サーバーに自動送信されるので、認証情報やセッションIDを保存するのに向いています。ただし、セキュリティを考慮して、重要な情報は暗号化するか、HttpOnly属性を付ける必要があります。
4. IndexedDB:大容量で柔軟な保存
IndexedDBは、数GBという大きな容量を保存できるデータベースです。非同期APIで、オブジェクトやBlobなど、様々なデータ型を保存できます。インデックスを設定して検索も可能です。
使い方は少し複雑ですが、柔軟性が高いです。データベースを開いて、オブジェクトストアを作成し、トランザクションを使って保存・読み込みを行います。
// データベースを開く
const request = indexedDB.open('TestDB', 1);
request.onupgradeneeded = function(e) {
const db = e.target.result;
// オブジェクトストアを作成
if (!db.objectStoreNames.contains('data')) {
db.createObjectStore('data', { keyPath: 'id' });
}
};
request.onsuccess = function(e) {
const db = e.target.result;
// 保存
const transaction = db.transaction(['data'], 'readwrite');
const store = transaction.objectStore('data');
store.put({ id: 'testData', value: '保存するデータ' });
};
最初は非同期処理に慣れていなくて、データを保存した直後に読み込もうとして、まだ保存が完了していなくてエラーになりました。Promiseを使うか、トランザクションの完了を待つ必要があります。
大きなファイルや、複雑なデータ構造を扱うのに向いています。例えば、画像ファイルをBlobとして保存したり、大量のレコードをインデックスで検索したり。そんな用途に使えます。
実際に試してみると、保存と読み込みに少し時間がかかります。非同期処理なので、コールバックやPromiseで処理を待つ必要があります。
5. Download API:ファイルとして保存
Download APIは、ユーザーのダウンロードフォルダにファイルとして保存する方法です。メモリ制限内であれば、実質的に無制限の容量を保存できます。ファイル名を指定でき、Blob形式で保存します。
使い方は、Blobを作成して、ダウンロードリンクを生成します。
function saveDownload(data, filename) {
const blob = new Blob([data], { type: 'text/plain' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = filename;
a.click();
URL.revokeObjectURL(url);
}
ブラウザのダウンロードフォルダに保存されるので、ユーザーがファイルを管理できます。ただし、読み込む場合は、ユーザーが手動でファイルを選択する必要があります。
大きなデータを保存するのに向いています。例えば、エクスポート機能で、アプリのデータをJSONファイルとして保存する。そんな用途に使えます。
実際に試してみると、保存ボタンを押すと、ブラウザのダウンロードフォルダにファイルが保存されます。ただし、読み込む場合は、ファイル選択ダイアログから手動で選ぶ必要があります。
6. File System Access API:ファイルを直接操作
File System Access APIは、ファイルやディレクトリに直接アクセスできる方法です。ディスク容量内であれば、実質的に無制限の容量を保存できます。保存場所をユーザーが選択でき、Chromium系ブラウザ(Chrome、Edgeなど)のみ対応しています。
使い方は、ファイル選択ダイアログを表示して、ファイルハンドルを取得します。
// 保存
async function saveFileSystem(data) {
const fileHandle = await window.showSaveFilePicker({
suggestedName: 'test-data.txt',
types: [{
description: 'Text file',
accept: { 'text/plain': ['.txt'] }
}]
});
const writable = await fileHandle.createWritable();
await writable.write(data);
await writable.close();
}
// 読み込み
async function loadFileSystem() {
const [fileHandle] = await window.showOpenFilePicker({
types: [{
description: 'Text file',
accept: { 'text/plain': ['.txt'] }
}]
});
const file = await fileHandle.getFile();
const text = await file.text();
return text;
}
最初は非同期処理に慣れていなくて、awaitを忘れてエラーになりました。また、Chromium系ブラウザでしか動かないので、他のブラウザでは代替手段が必要です。
ユーザーが保存場所を選べるので、ファイル管理アプリのような用途に使えます。ただし、セキュリティ上の理由で、ユーザーの操作(クリックなど)をトリガーにする必要があります。
実際に試してみると、保存ボタンを押すと、ファイル保存ダイアログが表示されます。ユーザーが保存場所を選ぶと、そこにファイルが保存されます。
6つの方法を比較
それぞれの特徴を表にまとめました。用途に応じて選ぶ参考にしてください。
試行錯誤の過程
最初は、全部localStorageで済ませようと思っていました。でも、実際に使ってみると、容量制限に引っかかったり、オブジェクトをそのまま保存できなかったり、タブを閉じても残したいのに消えたり。そんな経験を重ねました。
1回目の試行では、localStorageに大きなJSONを保存しようとして、容量オーバーになりました。約5MBという制限は、思ったより小さいです。
2回目の試行では、オブジェクトをそのまま保存しようとして、[object Object]という文字列になってしまいました。JSONに変換する必要があることを学びました。
3回目の試行では、IndexedDBを使おうとして、非同期処理に慣れていなくて、データを保存した直後に読み込もうとしてエラーになりました。Promiseを使うか、トランザクションの完了を待つ必要があることを学びました。
最終的には、用途に応じて使い分けるのが最適だと分かりました。小さな設定値はlocalStorage、一時的なデータはsessionStorage、大きなデータはIndexedDB、ファイルとして保存したい場合はDownload APIやFile System Access API。それぞれの特徴を理解して、適切な方法を選ぶことが大切です。
パフォーマンスの違い
実際に測定してみると、保存と読み込みの速度に違いがあります。
localStorageとsessionStorageは、同期的に動作するので、保存と読み込みが即座に完了します。ただし、大きなデータを保存すると、ページの読み込みが少し重くなる可能性があります。
IndexedDBは、非同期で動作するので、保存と読み込みに少し時間がかかります。ただし、大きなデータを扱えるので、パフォーマンスと容量のバランスが取れています。
Download APIとFile System Access APIは、ファイルシステムにアクセスするので、ネットワークの速度やディスクの速度に依存します。ただし、実質的に無制限の容量を保存できるので、大きなファイルを扱うのに向いています。
まとめ
ブラウザでデータを保存する6つの方法を試してみました。それぞれに特徴があり、用途に応じて選ぶ必要があります。
- localStorage:シンプルな永続保存。約5〜10MB。文字列のみ。
- sessionStorage:タブごとの一時保存。約5〜10MB。タブを閉じると消える。
- Cookie:小容量でサーバーに送信。約4KB。有効期限を設定可能。
- IndexedDB:大容量で柔軟な保存。数GB。オブジェクトやBlobを保存可能。
- Download API:ファイルとして保存。メモリ制限内で実質無制限。
- File System Access API:ファイルを直接操作。Chromium系ブラウザのみ対応。
実際に触ってみると、それぞれの違いが体感できます。用途に応じて、適切な方法を選ぶことが大切です。
さらに深く学ぶには