demo · v141

Keys then Values

A document list where the cheap metadata (id + title + size) loads via getAllKeys({ direction: "prev" }), then the heavy body loads on click. The new direction option finally lets you do "show newest 50 file titles, fetch contents only on demand" without iterating a cursor.

checking support…

Seeds 50 fake documents (each with a 30-50KB body). The list below shows newest first; click any row to lazy-load the body.

the call

// Cheap initial paint — keys only, newest first
const tx = db.transaction("docs", "readonly");
const store = tx.objectStore("docs");
const recentKeys = await new Promise((res, rej) => {
  const req = store.getAllKeys(null, 50);
  // direction option new in 141 — was only "next" implicit before
  req.direction = "prev";
  req.onsuccess = () => res(req.result);
  req.onerror = () => rej(req.error);
});

// Lazy body fetch on click
async function loadBody(key) {
  return new Promise((res) => {
    store.get(key).onsuccess = (e) => res(e.target.result);
  });
}

why this angle

The Microsoft Edge explainer calls out "deferred value loading" as a use case the direction option specifically enables: fetch keys (cheap metadata via the keypath) first, then defer the bulk read until the user actually needs the contents. This pattern is everywhere — file pickers, notes apps, mail clients, photo libraries. Before 141, you'd have to read keys in insertion order then reverse client-side, or you'd waste a full getAll on contents you'll never display.

see also