Die IndexedDB als großer Datenspeicher eignet sich meiner Meinung nach ziemlich gut als generischer Cache. Localstorage ist nett, um einzelne Dinge zu speichern, z.B. den Inhalt eines einzigen Textfeldes oder die Position der Scrollbar eines Multiselect-Feldes, aber mit 2,5 MB ist der Nutzen begrenzt. IndexedDB, mit 50 MB im Firefox - mehr mit Nutzererlaubnis - und 20% des verfügbaren Speicherplatzes in Chrome - was die Hälfte der Festplatte sein dürfte, wenn ich das richtig lese - eignet sich da schon für mehr.
Beispielweise cache ich damit die Lyrics im music-streamer, und wenn der Browsersupport das hergibt, möchte ich damit die Lieder selbst cachen (das geht noch nicht).
Leider ist die indexedDB-Api meiner Meinung nach hässlich und kompliziert. Sie ist beherrschbar, aber ich musste mich da ein bisschen durchkämpfen. Herausgekommen ist folgender Code:
var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
function cache(id, data) {
var request = indexedDB.open("cache", 1);
request.onupgradeneeded = function (event) {
event.target.result.createObjectStore("cache");
};
request.onsuccess = function(event) {
var db = event.target.result;
var transaction = db.transaction(["cache"], 'readwrite');
transaction.objectStore("cache").put(data, id);
};
}
function getCached(id, success) {
var request = indexedDB.open("cache", 1);
request.onupgradeneeded = function (event) {
event.target.result.createObjectStore("cache");
};
request.onsuccess = function(event) {
var db = event.target.result;
var transaction = db.transaction(["cache"], 'readwrite');
transaction.objectStore("cache").get(id).onsuccess = function (event) {
success(event.target.result);
};
};
}
Damit kann nun beliebiges gecached und wieder geholt werden:
getCached(id, function(res) {
if (res == undefined) {
res = getData(id);
cache(id, res);
}
useData(res);
});
Die Datei liegt als cache.js auf github.