How can I get the size and/or number of elements in a ServiceWorker cache?
Asked Answered
D

2

9

ServiceWorker is a new api available in Chrome. One of the many things it lets you do is intercept network requests and respond with a cached version. I'm implementing a "take this offline" button which dynamically adds things to the cache. I'd like to report to the user how much space I'm using, and how many entries I've put in the cache.

Is it possible to query a cache to get the number of items in it? Can I report the total size of things cached in it?

Daph answered 5/2, 2015 at 5:49 Comment(2)
As mentioned in the answer below, you can use cacheName.keys().then(function(keys) { keys.length }). Currently there is no way to compute the size on disk, but you can look at the content-size header for each response, but it will not exactly match whats stored on disk. (Also some http servers don't set content-size correctly.) There is open spec work around this with the quota-api and on ServiceWorkers here: github.com/slightlyoff/ServiceWorker/issues/587Kao
Thanks @BenKelly for the link to the discussion on that github issue. I'll weigh in with my 2 cents.Daph
G
2

Apparently you can use cacheName.keys().length as shown in trained to thrill, you can also cycle on the single entries and compute the total weight.

Garrulity answered 5/2, 2015 at 8:28 Comment(2)
Thanks for the github source link. I can see that will work for my purposes but seems like it could be possibly expensive to loop through all of the items in the cache to add up the size. Depending on the cache implementation, that could be a lot of reads. Ideally the cache object would keep a tally of the size of the items it contains and update it as items are added and removed.Daph
return caches.open(CACHE_NAME) .then(function (cache) { cache.keys().then(function (keys) { cachedItemCount = keys.length; }); });Teary
A
9

You can do something like the following to find the approximate size of the cache:

// returns approximate size of a single cache (in bytes)
function cacheSize(c) {
  return c.keys().then(a => {
    return Promise.all(
      a.map(req => c.match(req).then(res => res.clone().blob().then(b => b.size)))
    ).then(a => a.reduce((acc, n) => acc + n, 0));
  });
}

// returns approximate size of all caches (in bytes)
function cachesSize() {
  return caches.keys().then(a => {
    return Promise.all(
      a.map(n => caches.open(n).then(c => cacheSize(c)))
    ).then(a => a.reduce((acc, n) => acc + n, 0));
  });
}

There's a few caveats:

  • Counts the size of the response body only. (This could be partially fixed.)
  • Counts non-opaque responses. (This can't be fixed.)
Acreinch answered 12/4, 2017 at 14:50 Comment(0)
G
2

Apparently you can use cacheName.keys().length as shown in trained to thrill, you can also cycle on the single entries and compute the total weight.

Garrulity answered 5/2, 2015 at 8:28 Comment(2)
Thanks for the github source link. I can see that will work for my purposes but seems like it could be possibly expensive to loop through all of the items in the cache to add up the size. Depending on the cache implementation, that could be a lot of reads. Ideally the cache object would keep a tally of the size of the items it contains and update it as items are added and removed.Daph
return caches.open(CACHE_NAME) .then(function (cache) { cache.keys().then(function (keys) { cachedItemCount = keys.length; }); });Teary

© 2022 - 2024 — McMap. All rights reserved.