Performance optimization: multiple browser.storage queries vs caching everything in background script

Let’s say I want to write an add-on to append sticky notes to websites. On every tabs.onUpdated, the extension must check if there are notes to be added to the page. Should I permanently load all the stored data to addon background for quick access or should I run storage.local.get every time?

Which one would be more efficient? Is there any way to compare execution time / memory usage / CPU usage? Or a simple answer based on how browser.storage works.

I guess that load everything to memory would be preferable for small data, while querying the storage would be better for larger data. But what’s the inflection point?

1 Like

Usually it’s best to keep things simple and readable :slight_smile:.
If you are unsure and you really need to know, then test it on a real data - you can measure it precisely with performance.now().

But as a person who likes to over-optimize things I would totally optimize the crap out of it :smiley:.

Since most of your queries will be “not found” (since most of the page you visit won’t have any notes I suppose), I would go with a combined approach - use simple Set() to store URLs of pages that have notes. Then if there is a match, query the store for the data.
This approach is memory friendly and crazy fast. But if it’s just text notes, then just keep it all in the memory, it’s not like it’s gonna be more than a few MB ever, right? (that would be a millions characters)

However based on the quick test on my fast desktop I can tell you that async query to the store requesting non-existing data takes 2ms!!!
But then again, I’m pretty sure using the Set you will get it in 0ms and avoid IO operation potentially resulting into database log being written on my SSD :smiley: (this is my optimized-focused part of my brain talking).

2 Likes

Right. I’m pretty sure that, for that case, keeping everything in memory would be the best choice, the fastest approach and memory is a non-issue.

Maybe it’s more curiosity to know how things work on the worst case scenario (when there’s a lot of data and memory is gold). uBlock Origin appears to use IndexedDB, I wonder why, if it’s faster than browser.storage. Also I don’t know if it keeps everything in memory. I guess I can trust uBO as the inspiration on optimization.

Edit: apparently, uBO uses IndexedDB because browser.storage used to perform bad:

But since Firefox 62, browser.storage and IndexedDB are essentially the same thing:

So maybe it’s just that gorhill didn’t have time or motivation yet to move back to browser.storage, but it looks that it’s not that IndexedDB is better than browser.storage (not anymore).

1 Like

I had a lot of problems with IndexedDB as it’s used to be pretty buggy in Firefox and also Chrome. It’s much better now but still, some of the bugs I’ve reported are still opened (and it’s usually some hard to reproduce race condition).

Anyhow, I would suggest you to avoid IndexedDB if you can :slight_smile:. Unless you need to store Blobs (like files or images), then it’s the only good choice.

You could also use “storage.sync” to sync user data across devices - but it can hold only 100KB. But in terms of performance it’s still locally saved and the sync happens only seconds / minutes later.