1

I am developing a Chrome extension that tracks how long you have been using your computer. I increment using an interval, and am checking if the computer is locked using chrome.idle.queryState, and if it is locked I don't change my counter.

Is there a way to manually unload a background page, rather than constantly checking with an interval? Or does the background script ever unload and reload automatically, like after the computer is sleeping for X minutes? Since I have an interval, I wonder if the script will ever unload on its own. I do something similar to this:

setInterval(function () {
    chrome.idle.queryState(15, function (state) {
        if (state !== "locked") {
            counter += 1;
            console.log(counter);
        }
    }
}, 6000);
derek
  • 13
  • 5
  • You can use `window.close()` but it's a bad method. The proper method is to rework your code to use a [non-persistent background script](https://developer.chrome.com/docs/extensions/mv2/background_migration/). – wOxxOm Jan 03 '21 at 06:44
  • 1
    Note that the way you're using setInterval here is terribly inefficient: it runs the code constantly with nearly 100% CPU load in the extension process. – wOxxOm Jan 03 '21 at 07:01
  • Why do you need to constantly check? any reason you can't use chrome.idle.onStateChanged? – Nadia Chibrikova Jan 03 '21 at 08:32
  • @wOxxOm I set the background script with persistent equal to false to begin with. I also forgot to add a 6,000 at the end so it runs every 6 seconds (just edited it again). What do you mean by 100% CPU load? What does having a persistent vs. non-persistent script do (in the documentation it just said use non-persistent for webRequest api)? – derek Jan 03 '21 at 14:59
  • @NadiaChibrikova I think that might work, thanks for the suggestion! – derek Jan 03 '21 at 15:01
  • a) 100% CPU load would happen if you don't specify 6000. b) The background script will unload automatically after 15-30 seconds regardless of setInterval. Just make sure you don't inspect it in devtools and don't have any ports opened via chrome.runtime messaging. – wOxxOm Jan 03 '21 at 15:10
  • @wOxxOm, thanks so much! This makes a lot of sense. In the future, if I wanted to add messaging (from a popup), would it mean that the background script would never unload? – derek Jan 03 '21 at 16:12
  • Normal messaging won't be a problem. – wOxxOm Jan 03 '21 at 18:05
  • @wOxxOm, what is the difference between chrome.runtime messaging and normal messaging? I am planning on sending messages with chrome.runtime.onMessage.addListener for the background script, would this count as an open port? – derek Jan 03 '21 at 19:24
  • It's the same thing. An open port means the port intentionally left open for asynchronous call via `return true` ([info](https://stackoverflow.com/a/20077854)) or a port created via chrome.runtime.connect. Such open ports prevent unloading of the background script. – wOxxOm Jan 03 '21 at 23:11

1 Answers1

0

Thanks to wOxxOm and Nadia Chibrikova for answering the question. In unloading the script, it is best to use a non-persistent background script, like so:

...
"background": {
    "scripts": ["background.js"],
    "persistent": false
},
...

This would unload after 15-30 seconds regardless of any intervals, as long as there are no open message ports and you don't inspect it in devtools. For my purposes, I am keeping a message port open, so I use a variable to keep track of whether Chrome is idle or not by using chrome.idle.onStateChanged, and modified my code accordingly, with this:

chrome.idle.setDetectionInterval(15);
chrome.idle.onStateChanged.addListener(function (state) {
    if (state === "locked") {
        isLocked = true;
    } else {
        isLocked = false;
    }
});
derek
  • 13
  • 5