Event pages are very similar to background pages, with one important difference: event pages are loaded only when they are needed. When the event page is not actively doing something, it is unloaded, freeing memory and other system resources.
{{?is_apps}}Chrome Apps always use event pages instead of background pages. It is not possible for a Chrome App to have a persistent background page.
{{/is_apps}}Event pages are available in the stable channel as of Chrome 22, and the performance advantages are significant, especially on low-power devices. Please prefer them to persistent background pages whenever possible for new development and begin migrating existing background pages to this new model.
Register your event page in the extension manifest:
{{^is_apps}}{ "name": "My extension", ... "background": { "scripts": ["eventPage.js"], "persistent": false }, ... }
Notice that without the "persistent" key, you have a regular background page. Persistence is what differentiates an event page from a background page.
{{/is_apps}} {{?is_apps}}{ "name": "My app", ... "background": { "scripts": ["eventPage.js"] }, ... }{{/is_apps}}
The event page is loaded when it is "needed", and unloaded when it goes idle again. Here are some examples of things that will cause the event page to load:
$ref:runtime.getBackgroundPage
.
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). Additionally, the event page will not unload until all visible views (for example, popup windows) are closed and all message ports are closed. Note that opening a view does not cause the event page to load, but only prevents it from closing once loaded.
Make sure your event page closes as soon as the event that opened it is processed. You can observe the lifetime of your event page by opening Chrome's task manager. You can see when your event page loads and unloads by observing when an entry for your extension appears in the list of processes.
Once the event page has been idle a short time
(a few seconds), the
$ref:runtime.onSuspend
event is dispatched. The event page has a few more seconds to handle this
event before it is forcibly unloaded. If during this time an event occurs which
would normally cause the event page to be loaded, the suspend is canceled
and the $ref:runtime.onSuspendCanceled
event is dispatched.
Chrome keeps track of events that an app or extension has added listeners
for. When it dispatches such an event, the event page is
loaded. Conversely, if the app or extension removes all of its listeners for
an event by calling removeListener
, Chrome will no longer
load its event page for that event.
Because the listeners themselves only exist in the context of the
event page, you must use addListener
each time the event
page loads; only doing so at
$ref:runtime.onInstalled
by itself is insufficient.
For an example of event registration in action, you can view the Google Mail Checker extension.
Follow this checklist to convert your extension's (persistent) background page to an event page.
"persistent": false
to your manifest as shown above.
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.
$ref:extension.getBackgroundPage
,
switch to
$ref:runtime.getBackgroundPage
instead. The newer method is asynchronous so that it can start the event
page if necessary before returning it.
Keep these tips in mind when using event pages to avoid common subtle pitfalls.
$ref:runtime.onInstalled
event. This is a good place to register for
declarativeWebRequest rules,
contextMenu entries, and other such
one-time initialization.
$ref:tabs.onUpdated
event, try using the
$ref:webNavigation.onCompleted
event with filters instead (the tabs API does not support filters).
That way, your event page will only be loaded for events that
interest you.
$ref:runtime.onSuspend
event if you need to do last second cleanup before your event page
is shut down. However, we recommend persisting periodically instead.
That way if your extension crashes without receiving
onSuspend
, no data will typically be lost.
id
parameter to
$ref:contextMenus.create
,
and use the
$ref:contextMenus.onClicked
callback instead of an onclick
parameter to
$ref:contextMenus.create
.