Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Persistent background page on demand or an event page that doesn't unload?

I want to build a extension that behaves like a timer. It should count down the seconds when activated, but should do nothing with inactive.

The chrome.alarms API is interesting, but does not have enough precision nor granularity. It only fires at most once per minute, and it may fire late. If I want something to execute more often than that, I can't use this API.

Then, the next natural solution is to use a background page and use setTimeout or setInterval in there. However, background pages are persistent, and they take up resources (e.g. memory) even when idle. So they are not ideal.

The best solution seems to be an event page to run the timer. However, the documentation says:

Once it has been loaded, the event page will stay running as long as it is active (for example, calling an extension API or issuing a network request).

[…]

Once the event page has been idle a short time (a few seconds), the runtime.onSuspend event is dispatched. The event page has a few more seconds to handle this event before it is forcibly unloaded.

[…]

If your extension uses window.setTimeout() or window.setInterval(), switch to using the alarms API instead. DOM-based timers won't be honored if the event page shuts down.

Unfortunately, having an active setInterval is not enough to consider an event page active. In fact, from my tests, an interval up to 10 seconds is short enough to keep the event page running, but anything greater than 10 or 15 seconds is too far apart and the event page will get unloaded. I've tested this on my crx-reload-tab project.


I believe what I want is a middle ground:

  • I want a background page that I can load and unload on demand. (Instead of one that keeps loaded all the time.)
  • I want an event page that stays persistent in memory for as long as I say; but otherwise could be unloaded. (Instead of one that gets unloaded automatically by the browser.)

Is it possible? How can I do it?

like image 495
Denilson Sá Maia Avatar asked May 04 '16 02:05

Denilson Sá Maia


1 Answers

Background pages cannot be unloaded on demand, and Chrome decides Event page lifecycle for you (there is nothing you can do in onSuspend to prevent it).


If your concern is timers, you could try my solution from this answer, which basically splits a timer into shorter timers for a "sparse" busy-wait. That's enough to keep the event page loaded and is a viable solution if you don't need to do that frequently.


In general, there are some things that will keep an event page loaded:

If you're using message passing, be sure to close unused message ports. The event page will not shut down until all message ports are closed.

This can be exploited if you have any other context to keep an open Port to, for example a content script. See Long-lived connections docs for more details.


In practice, if you often or constantly need precise, sub-minute timers, an Event page is a bad solution. Your resource gains from using one might not justify it.

like image 84
Xan Avatar answered Jan 02 '23 20:01

Xan