Search code examples
google-chrome-extensionchrome-extension-manifest-v3

Avoid repeated storage calls in manifest v3 service worker listener


Considering a situation where network connections have to be processed based on user-set criteria, in MV2 with persistent background script, criteria can be cached to avoid repeated calls to the storage.

AFA I understand, that would not be possible in MV3.

Is there an alternative/better way to avoid repeated calls to the storage?

For example:

chrome.webRequest.onBeforeRequest.addListener(onRequest, {urls: ['<all_urls>']});

function onRequest(requestInfo) {
  /*   
    process
    ------------------
    1. get user preferences asynchronously e.g.
    await chrome.storage.local.get();

    2. loop through all criteria
    3. convert all patterns to RegExp
    4. check if they match the criteria
    5. prepare a process
    6. repeat the same for each request
  */
}

Note: Above listener is only an example and the question mainly relates to the caching of the storage data.


Update based on reply by wOxxOm
Would the following work?

// cache
let cache;

chrome.webRequest.onBeforeRequest.addListener(onRequest, {urls: ['<all_urls>']});

function onRequest(requestInfo) {
  /*   
    process
    ------------------
    1. check if cache is set
    if (!cache) {
      await prepareCache();
    }
    
    2. check if they match the criteria in cache
    3. prepare a process
    4. repeat the same for each request
  */
}

async function prepareCache() {
  /* 
    1. get user preferences asynchronously e.g.
    await chrome.storage.local.get();

    2. convert all patterns to RegExp
    3. save to cache 
  */
}

Solution

  • Currently MV3 is bugged so it won't even wake up the worker for webRequest, see workarounds.

    As for storage, you only need to read it once per waking up: example. It'll happen quite rarely if you you use the above workaround named "Persistent" service worker while a connectable tab is present.

    I also suggest using IndexedDB because it can store RegExp object directly so that your code won't lose a lot of time to recompile them. IndexedDB API is callback-based but there are simple Promise-based libraries around, and writing one yourself is easy enough.