シンプルな“TODOタスク管理アプリ”を作成しました – IndexedDB

SNOW

2025-10-16

ブラウザだけで動く「シンプルなTODOタスク管理アプリ」を作成しました。

特徴は、ローカルストレージではなく IndexedDB を使ってデータを保存できる点です。

IndexDBは、普通にあるものなのに初めて知ったということで、実装までに苦労したことや工夫した部分を中心にお話しします。

実際に動くアプリの仕組みや、WordPress環境での工夫も含めてまとめました。

なぜIndexedDBか

localStorageでは足りない理由

localStorageはシンプルですが、容量が数MB程度と限られており、文字列しか保存できず、タスクが増えたり、より多様な情報を扱いたくなった場合には不便です。

一方でIndexedDBは、オブジェクトをそのまま保存でき、容量も比較的大きく、構造化データを扱うのに向いています。

IndexedDBの特徴と対応ブラウザ

IndexedDBは非同期で動作し、トランザクションを使って安全にデータを扱うことができ、主要ブラウザ(Chrome、Firefox、Safari、Edgeなど)に対応しており、今後も安定して利用できる仕組みです。

また、最近では「永続化ストレージ(Persistent Storage)」にも対応し、ブラウザが自動でデータを削除しにくくする工夫も可能になっています。


設計・実装の流れと苦労した点

初期構成と基本操作

HTML+CSSの設計

最初にフォーム(タイトル、完了予定日、登録ボタン)と一覧テーブルを用意しました。
WordPressでの利用を想定し、IDの重複を避けるために wpidb- という接頭辞を付けて管理しました。
デザインはシンプルさを優先し、CSS変数で色やテーマを統一しました。

IndexedDBラッパの設計

IndexedDBはネイティブAPIが少し複雑なため、Promiseで扱いやすいラッパ関数を自作しました。
openDBaddTaskupdateTaskdeleteTaskgetAllTasks のような構成にし、画面処理とDB処理を分離しています。
苦労したのは、onupgradeneeded の設計とトランザクションの扱い、バージョンアップ時のスキーマ変更や、処理タイミングによるエラーを避けるための工夫が必要でした。


並び替えと表示の工夫

並び替えのルール

タスクの並び順は「進行中 → 未着手 → 完了」の順にし、期日とタイトルでもソートしています。

このため、タスク一覧が自然な順序で並ぶようになっています。

日本語タイトルのソートでは localeCompare を使いましたが、同じ期日のときに順序が安定しない問題があり、細かい条件分岐を入れて調整しました。


完成したTODOアプリ

※ 並び順は「進行中 → 未着手 → 完了」→「期日」→「タイトル」です。
タイトル完了予定日ステータス操作

WordPress埋め込みとキャッシュの壁

プレビューで動かない問題

WordPressのプレビュー環境ではスクリプトが動作せず、登録ボタンを押しても反応しない状態がありました。

原因は、最適化プラグインがインラインスクリプトを削除・圧縮していたことです。

対策として、スクリプトを外部ファイル化し、次のような工夫をしました。

  • <script src="..."></script> 形式に変更
  • <!--nooptimize--> タグで最適化を無効化
  • クエリパラメータ(例:?ver=20251016-2)を付けてキャッシュを更新

この対応で、更新が反映されない問題も解消されました。

構文エラー “Unexpected token ‘)’” の原因

IndexedDB復元処理に ??includes を使っていたため、一部の環境で構文エラーが発生しました。

これを三項演算子や従来のfunction表記に書き換え、互換性を確保しました。


実用性を高める工夫

  • JSON形式でのバックアップと復元を実装
  • 「未着手」「進行中」「完了」のフィルタボタンを追加
  • 期限超過タスクの自動赤色表示
  • CSSクラス設計を整理し、テーマ変更や拡張がしやすい構造に変更

今後は、通知機能やPWA化などの拡張も検討しています。


あるある・疑問・質問

Q. IndexedDBのデータは消えることがありますか?
通常の利用では削除されませんが、ストレージ不足やブラウザのキャッシュ削除時に消える可能性があります。
Persistent Storage設定を利用することで、より安全に保持できます。

Q. どのブラウザでも動きますか?
主要ブラウザでは動作しますが、古いバージョンやInternet Explorerでは非対応です。
互換性を重視する場合はlocalStorageを併用する方法もあります。

Q. 他のデータベースとの違いは?
FirebaseやSQLiteのような外部DBは共有や同期に強みがあります。
一方でIndexedDBはローカル専用で、オフラインでも動作する点が大きな利点です。


ローカルDBだけで十分か?

ローカルDBで完結する仕組みは軽量で使いやすい反面、いくつかの課題もあります。

  • 複数デバイス間の同期ができない
  • バックアップや暗号化などの保護は自前で必要
  • ブラウザの設定によっては削除されることもある

個人利用や簡易管理には最適ですが、チーム運用や長期保存を考える場合は、サーバー側との同期を組み合わせるのが理想です。


出典:ピーターのりお

まとめ

前から作ってみたかった、ブラウザのみで動作する軽量タスク管理アプリを作成しました。

実装ではキャッシュや最適化の壁、構文エラーなど多くの課題に直面しましたが、一つずつ解決していく過程で多くの学びがありました。

IndexedDBを使うことで、リロードしてもデータが残る快適なタスク管理が可能になりました。

こういうのも1時間かからずにできる時代が猛スピードで訪れていますが、まさにすさまじい勢いですよね。


参考リンク