queicherius / gw2api-client

Javascript wrapper for the official Guild Wars 2 API.
MIT License
47 stars 18 forks source link

Write a propper cache interface for the browser #9

Closed queicherius closed 6 years ago

queicherius commented 7 years ago

Requirements

Tested

bennieboj commented 7 years ago

Maybe LokiJS? http://lokijs.org/ https://codepen.io/Bennieboj/pen/wqrgJx?editors=1111

I'm unsure how you tested these in the past? It might be a good idea to test these libraries next to each other in something like jsperf? That was people can more easily contribute and add new libraries? This is the latest jsperf I could find using LokiJS: https://jsperf.com/lokijs-benchmarks/15

queicherius commented 7 years ago

I never tried the LokiJS persistence adapters, might be worth a try. Thanks!

GeeWizWow commented 6 years ago

Hey

I've used redux-persist in the past with success. It ticks a couple of your boxes:

Of course this assumes the usage of redux. https://github.com/rt2zz/redux-persist

queicherius commented 6 years ago

Sadly redux-persist under the hood just uses basic localStorage (see above):

localStorage: Fast reads/writes (< 1ms per item), but no batch operations, low storage limit and blocking

GeeWizWow commented 6 years ago

Afaik it will default to local storage if there are no other options. There’s a section at the very bottom of the readme on the diff storage engines On Sun, 18 Feb 2018 at 03:18, David Reeß notifications@github.com wrote:

Sadly redux-persist under the hood just uses basic localStorage (see above):

localStorage: Fast reads/writes (< 1ms per item), but no batch operations, low storage limit and blocking

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/queicherius/gw2api-client/issues/9#issuecomment-366489476, or mute the thread https://github.com/notifications/unsubscribe-auth/AIlRkijzFAALxfVlH9BF58c--MoFw2OOks5tV5aEgaJpZM4LC-PS .

GeeWizWow commented 6 years ago

The local forage provider claims it will use indexedDB or Websql On Sun, 18 Feb 2018 at 03:20, Finn Scott ifinnscott@gmail.com wrote:

Afaik it will default to local storage if there are no other options. There’s a section at the very bottom of the readme on the diff storage engines On Sun, 18 Feb 2018 at 03:18, David Reeß notifications@github.com wrote:

Sadly redux-persist under the hood just uses basic localStorage (see above):

localStorage: Fast reads/writes (< 1ms per item), but no batch operations, low storage limit and blocking

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/queicherius/gw2api-client/issues/9#issuecomment-366489476, or mute the thread https://github.com/notifications/unsubscribe-auth/AIlRkijzFAALxfVlH9BF58c--MoFw2OOks5tV5aEgaJpZM4LC-PS .

queicherius commented 6 years ago

Now that I think about it, it might be worthwhile trying a mixed approach, where the hashmap of key -> value is not saved directly (aka each key has a single storage entry) but kept in memory and instead saved as a single object into storage after it's not been written to in a few ms. On pageload we could then pre-populate the memory hashmap with the stored one. That should fix quite a few perf issues with everything I tried so far.

The local forage provider claims it will use indexedDB or Websql

I've tried that before (see above), but it might be worthwhile revisiting with the "single save" idea. That should give us non-blocking writes and reads but I dont know how much storage (I dont want to ask for user permission). Would probably have to find a different library tho, 8KB is pretty hefty just for saving something, maybe this one: https://www.npmjs.com/package/idb-keyval

GeeWizWow commented 6 years ago

From the idb docs page

Since this is IDB-backed, you can store anything structured-clonable (numbers, arrays, objects, dates, blobs etc).

That's nice.

So... If i follow you

// pseudo code
const createMeOnPageLoad = {
   ...readFromApi(),
   ...readFromCacheAsync(),
};

The issue that might occur with non-blocking reads, is a race condition with the ApiCall where new data is overwritten with stale data from the cache, although a simple versioning system could fix that (timestamp ?)