New in Chrome 22: Kill background pages, get featured in Web Store

3,374 views
Skip to first unread message

Aaron Boodman

unread,
Aug 27, 2012, 4:33:37 PM8/27/12
to chromium-extensions, Benjamin Kalman, Matt Perry, Yoyo Zhou
Hello extension developers!

In Chrome 22, we’re releasing two new APIs that we hope you’ll use to kill off your memory-guzzling background pages:

  • Event pages are a replacement for background pages. They are similar to background pages, except that they are automatically destroyed by the system when idle, and brought back to life when needed. Converting to event pages is usually really easy, and will improve Chrome’s performance and responsiveness -- especially on lower-power devices.
  • The Storage API is a replacement for HTML5’s localStorage, but with a couple big advantages. The Storage API can be used within content scripts directly, without having to send messages to a background page. This should allow many extensions to completely remove their background pages. The Storage API also has built-in support for synchronization. Any data stored within the sync namespace is automatically replicated to each device the user has your extension installed on.

To add some extra incentive, we’ll be featuring the awesomest extensions that kill their background pages using either of these APIs in the Chrome Web Store. Featured extensions periodically show up at the top of the extensions category, with gigantic promotional images that are pretty much impossible to miss. We'll also be selecting a few of these extensions to showcase in an upcoming blog post. To be eligible, just upload your converted, background-page-free extension to the Chrome Web Store by October 1.

Note that both these new APIs require manifest version 2. We plan to require manifest v2 for updates to all existing extensions starting in Chrome 23, so this is a good thing to start looking at now anyway.

So get out your editor and a scalpel, and let us know how these APIs work for you. If you have any questions, just reply to this message, or start a new thread on the mailing list.

Happy hacking,

- Ben (storage), Matt (event pages), Yoyo (event pages), and Aaron (overhead)

CGS

unread,
Aug 27, 2012, 5:08:06 PM8/27/12
to Aaron Boodman, chromium-extensions, Benjamin Kalman, Matt Perry, Yoyo Zhou
Is this a joke? Because if it is, it is really a bad one. Where do you get these ideas from?

1. You are punching your breasts with your fists saying you are working for securing the extensions (like killing eval and splitting the extensions scripts in 3 independent worlds which can exchange information via DOM or messages), yet you add the most insecure element as being the main instrument of persistence. Great thinking!

2. The DOM connection in between the background (event) page and its popup counterpart will just be killed in a periodical check (or longer period of activity, for that matter) because the background (event) page will be destroyed due to inactivity. Again, great thinking!

If you really want to see no extensions in your great browser, just say it so and don't bring this kind of arguments.

A very unhappy extension developer,
CGS




--
You received this message because you are subscribed to the Google Groups "Chromium-extensions" group.
To post to this group, send email to chromium-...@chromium.org.
To unsubscribe from this group, send email to chromium-extens...@chromium.org.
For more options, visit this group at http://groups.google.com/a/chromium.org/group/chromium-extensions/?hl=en.

Aaron Boodman

unread,
Aug 27, 2012, 5:13:43 PM8/27/12
to CGS, chromium-extensions, Benjamin Kalman, Matt Perry, Yoyo Zhou
On Mon, Aug 27, 2012 at 2:08 PM, CGS <cgsmc...@gmail.com> wrote:
> 1. You are punching your breasts with your fists saying you are working for
> securing the extensions (like killing eval and splitting the extensions
> scripts in 3 independent worlds which can exchange information via DOM or
> messages), yet you add the most insecure element as being the main
> instrument of persistence. Great thinking!

Sorry, I don't understand this one. What 'instrument of persistence'
are you referring to?

> 2. The DOM connection in between the background (event) page and its popup
> counterpart will just be killed in a periodical check (or longer period of
> activity, for that matter) because the background (event) page will be
> destroyed due to inactivity. Again, great thinking!

The popup (or any other piece of extension UI, like an options page)
keeps event pages alive.

- a

Matt Kruse

unread,
Aug 27, 2012, 5:23:21 PM8/27/12
to chromium-...@chromium.org, Benjamin Kalman, Matt Perry, Yoyo Zhou
I'm almost done making the changes as described below. It's working better, and is much cleaner.
The problem I'm facing is that some users are still on Chrome 18.x. For them, chrome.storage.* doesn't exist, so I guess I need to have code that fails back to localStorage, just in case?

chrome.storage.sync sounded great at first, but the size and frequency restrictions are just too limiting for me. I'll need to learn more about them to figure out if I can work around it.

I'm glad to see more capability being directly offered to content scripts. I'm happy to kill my background page!

Matt Kruse
https://chrome.google.com/webstore/detail/ifmhoabcaeehkljcfclfiieohkohdgbb?hl=en

Scott Fujan

unread,
Aug 27, 2012, 5:24:22 PM8/27/12
to Aaron Boodman, CGS, chromium-extensions, Benjamin Kalman, Matt Perry, Yoyo Zhou
I believe that these changes are definitely in a positive direction -- just so long as a manifest v3 doesn't force all background pages to be event pages in the future.

A couple questions:

* Does a setTimeout work to keep the page alive?

* Can functionality be added to allow persistent background pages the explicit use of these features by calling window.close()? I did a quick test and the background page remained closed after a click of a browser button. Would this make sense to you?

(I've recently been getting back up to speed with the changes to Chrome after a year hiatus. Please feel free to point out any other major changes coming down the pipeline -- Thanks!)

Aaron Boodman

unread,
Aug 27, 2012, 5:29:04 PM8/27/12
to Duane O'Brien, chromium-extensions, Benjamin Kalman, Matt Perry, Yoyo Zhou
On Mon, Aug 27, 2012 at 2:27 PM, Duane O'Brien <duane....@gmail.com> wrote:
>> The Storage API is a replacement for HTML5’s localStorage, but with a couple
>> big advantages.
>
> Does this mean localStorage is no longer available in the context of a
> background page / event page? If not, will that be the case down the
> line?

No, sorry for the poor wording. localStorage is still available, and
we don't have any plans (or even ideas) to remove it. That said, we
think the storage API is better in most ways, so we'd be curious to
know why you can't use it.

- a

Yoyo Zhou

unread,
Aug 27, 2012, 5:51:42 PM8/27/12
to Scott Fujan, Aaron Boodman, CGS, chromium-extensions, Benjamin Kalman, Matt Perry
On Mon, Aug 27, 2012 at 2:24 PM, Scott Fujan <sc...@fujan.name> wrote:
> I believe that these changes are definitely in a positive direction -- just
> so long as a manifest v3 doesn't force all background pages to be event
> pages in the future.
>
> A couple questions:
>
> * Does a setTimeout work to keep the page alive?

No, but there is a new alarms API
(http://developer.chrome.com/beta/extensions/alarms.html) for this
purpose.

> * Can functionality be added to allow persistent background pages the
> explicit use of these features by calling window.close()? I did a quick test
> and the background page remained closed after a click of a browser button.
> Would this make sense to you?

Do you mean that you would want your closed persistent background
page to be reawakened upon getting an event? Is there a use case for
this that plain event pages wouldn't serve? If so, please file a
feature request at http://new.crbug.com and we'll look into it.

Yoyo Zhou

Aaron Boodman

unread,
Aug 27, 2012, 5:57:07 PM8/27/12
to Matt Kruse, chromium-...@chromium.org, Benjamin Kalman
On Mon, Aug 27, 2012 at 2:23 PM, Matt Kruse <matthew...@gmail.com> wrote:
> I'm almost done making the changes as described below. It's working better,
> and is much cleaner.

That is good to hear, thanks.

> The problem I'm facing is that some users are still on Chrome 18.x. For
> them, chrome.storage.* doesn't exist, so I guess I need to have code that
> fails back to localStorage, just in case?

Yes. In general, Chrome's autoupdate system does a really good job of
keeping the vast majority of users 1 major version behind or less. But
there are cases (such as enterprise deployments, or Chromium) where
users are on older versions. You'll have to look at your usage and try
and gauge how quickly you can take advantage of newer features.

We've tried to structure things so that graceful fallback is possible.
In this case, you should just be able to use runtime detection:

if (chrome.storage) {
// use it
} else {
// use local storage instead
}

> chrome.storage.sync sounded great at first, but the size and frequency
> restrictions are just too limiting for me. I'll need to learn more about
> them to figure out if I can work around it.

We recently doubled QUOTA_BYTES_PER_ITEM from 2k to 4k. If you are
hitting frequently limits, you probably need to look into batching
your updates somehow, or intelligently detecting changes.

- a

Duane O'Brien

unread,
Aug 27, 2012, 5:27:10 PM8/27/12
to Aaron Boodman, chromium-extensions, Benjamin Kalman, Matt Perry, Yoyo Zhou
> The Storage API is a replacement for HTML5’s localStorage, but with a couple
> big advantages.

Does this mean localStorage is no longer available in the context of a
background page / event page? If not, will that be the case down the
line?

-D

--
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Ideas are good things to have even if they are old.

Duane O'Brien

unread,
Aug 27, 2012, 5:33:20 PM8/27/12
to Aaron Boodman, chromium-extensions, Benjamin Kalman, Matt Perry, Yoyo Zhou
>> Does this mean localStorage is no longer available in the context of a
>> background page / event page? If not, will that be the case down the
>> line?
>
> No, sorry for the poor wording. localStorage is still available, and
> we don't have any plans (or even ideas) to remove it. That said, we
> think the storage API is better in most ways, so we'd be curious to
> know why you can't use it.

When writing code that might be shared between extensions or in
different contexts (different browsers, or libraries that exist
outside an extension world), I'd prefer not using vendor specific APIs
where possible. But I was more gauging if I needed to aggressively
prioritize migrating to the storage API over localStorage.

Scott Fujan

unread,
Aug 28, 2012, 12:05:20 AM8/28/12
to Yoyo Zhou, Aaron Boodman, CGS, chromium-extensions, Benjamin Kalman, Matt Perry
I have suggested a couple use cases in this bug: crbug.com/145168

Thanks!

PhistucK

unread,
Aug 28, 2012, 7:53:39 AM8/28/12
to Aaron Boodman, chromium-extensions, Benjamin Kalman, Matt Perry, Yoyo Zhou
I tried to convert my background page to an event page, but I ran into some weird issue.

My old background page was actually responsible for periodically (setInterval of 10 minutes) running a function.
(The function fetches some page and does executeScript in response to that fetch approximately once a day (when a certain condition is met, otherwise, it does nothing after fetching)).

So, I added (to support both of the versions of Chrome, with and without event pages) -
if (chrome.alarms)
 chrome.alarms.create({"when": 1000, "periodInMinutes": 1});
 alert("added a listener");
 chrome.alarms.onAlarm.addListener(run);
}
else
{
 run();
 setInterval(run, 600000);
}
The thing is, that alert is shown every time the page wakes up.

What is exactly expected in this model?

Should I be using the onInstalled/onStartup events? but, then, it will add a listener to those events every time the page is wakened (I know it will never actually fire all of the redundant listeners), which sounds like a bad practice/memory leak of some sort.

Note that I cannot use the various storage APIs, because I want to set the alarm every time the background page is... well, initially loaded? hehe.
So, say Chrome crashes, I cannot clean up the value I stored (which I would have done using onunload or something?) and, since I count on that value for setting the alarm, I will never set the alarm again.

Am I missing something?

Also, the documentation for chrome.alarms does not mention you need to add the "alarms" permission to the manifest and the documentation for the manifest keys does not list it as well.

PhistucK



--

Scott Fujan

unread,
Aug 28, 2012, 9:55:23 AM8/28/12
to PhistucK, Yoyo Zhou, Chromium-extensions, Benjamin Kalman, Aaron Boodman, Matt Perry

I can't address all of your questions, but "when:1000" will make it run 1 second after you set your alarm, so remove it. Also, try setting the period to 10 minutes instead of 1 like you have it. Also, you may want to detect the alarm name in the listener to avoid any issues if you add another alarm. That said, I do find alarms in the context of event pages a bit confusing as well -- fleshing out the doc page could help a lot

Godmar Back

unread,
Aug 28, 2012, 10:08:36 AM8/28/12
to Aaron Boodman, chromium-extensions, Benjamin Kalman, Matt Perry, Yoyo Zhou
Are extension pages really a worthwhile target? It's true that Chrome
is an absolute memory hog that uses up most physical memory on any
small (<2GB) machine after medium periods of use, but when I look at
the memory statistics, extensions account for only a fraction of
memory use. The browser kernel is usually first and second, followed
by JavaScript rich pages (Google Mail, other Google Apps) that clock
in at hundreds of MB.

Generally, users recover by restarting all Chrome processes, which
would correct long-running extension pages (which may have a bloated
heap) as well.

- Godmar

Aaron Boodman

unread,
Aug 28, 2012, 10:11:47 AM8/28/12
to Scott Fujan, PhistucK, Yoyo Zhou, Chromium-extensions, Benjamin Kalman, Matt Perry
Hm, it sounds like we need some documentation on how event
registration works for event pages.

PhistucK is doing it correctly. The first time you ever listen to an
event within an extension version, the system records it so that it
can wake up your extension to receive the event. However, you must
call addListener() each time your event pages runs to associate the
bit of code you want to to run with the event.

You can an example of this in the Gmail Checker sample:
http://developer.chrome.com/beta/samples.html#bb57f7a0132cbeb36ad7e7bb0ab75c21704234ca

As a side note, the minimum period is typically 5 minutes, I believe,
but you can set it much lower when an extension is unpacked for
development. We'll add doc about this too.

Thanks for the feedback,

- a

Aaron Boodman

unread,
Aug 28, 2012, 10:30:40 AM8/28/12
to Godmar Back, chromium-extensions, Benjamin Kalman, Matt Perry, Yoyo Zhou
On Tue, Aug 28, 2012 at 7:08 AM, Godmar Back <god...@gmail.com> wrote:
> Are extension pages really a worthwhile target? It's true that Chrome
> is an absolute memory hog that uses up most physical memory on any
> small (<2GB) machine after medium periods of use, but when I look at
> the memory statistics, extensions account for only a fraction of
> memory use. The browser kernel is usually first and second, followed
> by JavaScript rich pages (Google Mail, other Google Apps) that clock
> in at hundreds of MB.

Yes, it's a very worthwhile target:

- If you have 10 extensions installed, each using 15 megs of RAM,
that's 150 megs. This is a pretty typical scenario for Chrome users.
It may be only "half a Gmail", but it's "three Calendars". Even on
desktop, freeing up this much memory to reduce swapping is a great
thing.

- Mobile devices frequently do not have swap. This means that the 150
megs of memory is actual physical RAM. Once these devices max out, the
only thing they can do is start killing processes. Since classic
background pages are not designed to be killed and restored, the only
option is to kill tabs instead. This is a really frustrating UX, and
just weird to prefer memory from idle extension processes over memory
from tabs.

- Long-lived processes suffer from leaks and fragmentation. Cleaning
up processes periodically should result in smaller, faster background
processes.

> Generally, users recover by restarting all Chrome processes, which
> would correct long-running extension pages (which may have a bloated
> heap) as well.

That's a rather sad solution, we'd prefer something better.

- a

PhistucK

unread,
Aug 28, 2012, 10:30:49 AM8/28/12
to Scott Fujan, Yoyo Zhou, Chromium-extensions, Benjamin Kalman, Aaron Boodman, Matt Perry
Addressing your points -
1. I actually wanted the code to run immediately (well, one second later, in that case) once (when the extension is installed/first loaded), so that was on purpose.
2. While I build and debug, I rather wait a minute and not ten (like I wrote in the description before the code). ;)
3. If I had given it a name (and no "when"), it would override itself every time the page is loaded - not so good, as the function may never run or something.

Thank you for your help and input.


PhistucK

PhistucK

unread,
Aug 28, 2012, 10:31:31 AM8/28/12
to Godmar Back, Aaron Boodman, chromium-extensions, Benjamin Kalman, Matt Perry, Yoyo Zhou
If you have several extensions that feature background pages, it can also be a few (or more) hundreds of MB. I guess it is worth it.

PhistucK

Aaron Boodman

unread,
Aug 28, 2012, 10:39:30 AM8/28/12
to Scott Fujan, PhistucK, Yoyo Zhou, Chromium-extensions, Benjamin Kalman, Matt Perry
Oh I just looked at PhistucK's code again, and realized my answer was
partially incorrect.

The alarms.create() call is only needed once if it is repeating
(created with periodInMinutes). You can call it each time your page
runs as well, but that isn't necessary. As long as the alarm has the
same name each time (or no name, as in this example) it will overwrite
itself.

Hooks for event listeners are needed on every load, as I described before.

So a basic, typical skeleton for using the alarms API would be:

chrome.runtime.onInstalled.addListener(function() {
chrome.alarms.create(...);
});

chrome.alarms.onAlarm.addListener(function(alarm) {
...
});

- a

PhistucK

unread,
Aug 28, 2012, 10:41:13 AM8/28/12
to Aaron Boodman, Scott Fujan, Yoyo Zhou, Chromium-extensions, Benjamin Kalman, Matt Perry


PhistucK



On Tue, Aug 28, 2012 at 5:11 PM, Aaron Boodman <a...@chromium.org> wrote:
Hm, it sounds like we need some documentation on how event
registration works for event pages.

PhistucK is doing it correctly. The first time you ever listen to an
event within an extension version, the system records it so that it
can wake up your extension to receive the event. However, you must
call addListener() each time your event pages runs to associate the
bit of code you want to to run with the event.

I did not quite get the last sentence.
addListener of what?
Why every time? that bit of code is already associated the first time. Or am I misunderstanding something basic here?
 

You can an example of this in the Gmail Checker sample:
http://developer.chrome.com/beta/samples.html#bb57f7a0132cbeb36ad7e7bb0ab75c21704234ca


The init is called on DOMContentLoaded, which (if I understand correctly) should fire every time the event page is wakened.
chrome.alarms.onAlarm.addListener is also called every time the page is wakened as well.

As a side note, the minimum period is typically 5 minutes, I believe,
but you can set it much lower when an extension is unpacked for
development. We'll add doc about this too.

A minute is for debugging only. I really want 10. 

PhistucK

unread,
Aug 28, 2012, 10:43:46 AM8/28/12
to Aaron Boodman, Scott Fujan, Yoyo Zhou, Chromium-extensions, Benjamin Kalman, Matt Perry
This skeleton does pretty much the same thing here, the listener function is added every time the page is wakened, so it would be called exponentially.
Am I missing something?

PhistucK

PhistucK

unread,
Aug 28, 2012, 10:45:49 AM8/28/12
to Aaron Boodman, Scott Fujan, Yoyo Zhou, Chromium-extensions, Benjamin Kalman, Matt Perry
Oh, now I get it. Sent too soon. ;)
I will try that.

Thank you!

PhistucK

Godmar Back

unread,
Aug 28, 2012, 10:47:01 AM8/28/12
to Aaron Boodman, chromium-extensions, Benjamin Kalman, Matt Perry, Yoyo Zhou
On Tue, Aug 28, 2012 at 10:30 AM, Aaron Boodman <a...@chromium.org> wrote:
only thing they can do is start killing processes. Since classic
background pages are not designed to be killed and restored, the only
option is to kill tabs instead. This is a really frustrating UX, and

I don't understand why extensions cannot be killed. 
Any extension's background page must survive a browser shutdown and restart, and for all practical purposes the extension cannot tell if just it was killed or the browser restarted. If anything, the user experience is less affected by an extension restart than a tab crash; an extension restart is much less noticable.

I agree though that this type of management, in general, is a frustrating user experience. I love Andries Brouwer's hilarious analogy: http://lwn.net/Articles/104185/

 - Godmar

Aaron Boodman

unread,
Aug 28, 2012, 10:48:07 AM8/28/12
to PhistucK, Scott Fujan, Yoyo Zhou, Chromium-extensions, Benjamin Kalman, Matt Perry
When you call chrome.foo.addListener(monkey), Chrome remembers that
your extension wants to receive the 'foo' event, even after your
extension process is shut down (and across restarts too).

However 'monkey' is a pointer to an in-memory function. Once your
extension's process is torn down this pointer is meaningless.

So, each time your extension process starts, you must again associate
a function to run in response to the 'foo' event. Otherwise, although
Chrome will deliver the event, nothing will happen.

- a

Aaron Boodman

unread,
Aug 28, 2012, 11:02:29 AM8/28/12
to Godmar Back, chromium-extensions, Benjamin Kalman, Matt Perry, Yoyo Zhou
On Tue, Aug 28, 2012 at 7:47 AM, Godmar Back <god...@gmail.com> wrote:
> On Tue, Aug 28, 2012 at 10:30 AM, Aaron Boodman <a...@chromium.org> wrote:
>>
>> only thing they can do is start killing processes. Since classic
>> background pages are not designed to be killed and restored, the only
>> option is to kill tabs instead. This is a really frustrating UX, and
>
> I don't understand why extensions cannot be killed.
> Any extension's background page must survive a browser shutdown and restart,
> and for all practical purposes the extension cannot tell if just it was
> killed or the browser restarted.

Wait, now you're arguing that not only should we have event pages -
they should be mandatory :)

Anyway, we definitely thought about just changing the behavior of the
current system.

It would work for some extensions, but for others it would be a
breaking change. For example window.setTimeout and window.setInterval
would just silently fail. These function calls are fairly common in
extensions, so if we just never shut down such extensions, we'd miss a
fair number.

chrome.extension.connect() is another case that would break. If we
shut down extension processes, existing content script connections
would be broken. Many extensions do not take care to inject into
currently open tabs when they load (because this doesn't typically
happen today), so these extensions would just stop working.

In short, we'd probably end up breaking a large number of extensions
if we did this. We decided it would be better to design a first class
API and to make it opt-in. If we ever have to force this behavior, at
least we will have

- a

Scott Fujan

unread,
Aug 28, 2012, 11:18:23 AM8/28/12
to Aaron Boodman, PhistucK, Yoyo Zhou, Chromium-extensions, Benjamin Kalman, Matt Perry
So a basic, typical skeleton for using the alarms API would be:

chrome.runtime.onInstalled.addListener(function() {
  chrome.alarms.create(...);
});

chrome.alarms.onAlarm.addListener(function(alarm) {
  ...
});

Is chrome.runtime.onInstalled the appropriate event? It seems like this would work the first time, but then fail the next time the browser started -- maybe events are persistent?

Also, I notice chrome.runtime.onStartup (This would be more appropriate?) is defined for the dev documentation, but is missing from the beta documentation. Is Chrome 23 the first version for which onStartup is available?

Godmar Back

unread,
Aug 28, 2012, 11:22:50 AM8/28/12
to Aaron Boodman, chromium-extensions, Benjamin Kalman, Matt Perry, Yoyo Zhou

I'd like to add another few considerations to better understand your thinking.

First, where global state is required - such as for user preferences or other configuration information, keeping it in a JavaScript object should be more efficient than keeping it in your new storage facility, by definition. Plus, having it in memory makes it easier to use it as, say, the angular model for a user preferences/configuration page.
So the true source of the overhead you're fighting is not the global state the extension must keep - provided it's written without significant memory leaks, it's the v8 state needed to hold these (few, and necessary), JavaScript objects. Is that correct?

Second, since communication between content scripts and the background page is so awkward, many extensions probably will reinject large parts of their codebase into the content script side. That's what we do, at least. This includes our inheritance framework, all utility classes, etc. etc. This code (and it's v8-compiled version) exists in every tab process, and an identical copy of it exists also in the background process, which uses the same codebase.

Taken together, I'm wondering if a better way to reduce the overall memory consumption of Chrome - all Chrome processes - wouldn't have been to enhance v8 to support under-the-hood, MVM- or KaffeOS-style [1,2] sharing of internal v8 data structures and, in particular, loaded source code and just-in-time compiled code - at least in cases where the code does not access its closure, which is true for much generic utility code. That is, the code accesses only its parameters, and the just-in-time compiled native code is the same in every process. It could be shared in the same way read-only .so shared libraries are shared. Has this been/is this being considered? It could, potentially, reduce the per-instance overhead for all v8 processes, shrinking extension processes in the process, and make the need to have ephemeral background page processes much less urgent.

One last thought: doesn't not having background processes (significantly) increase the latency when a popup is opened? I know for our extension, we would be pulling in a large amount of code - and asking v8 to compile it - every time the user invoked a browser action.

 - Godmar

[1] Grzegorz Czajkowski and Laurent Daynes. 2001. Multitasking without comprimise: a virtual machine evolution. In Proceedings of the 16th ACM SIGPLAN conference on Object-oriented programming, systems, languages, and applications (OOPSLA '01). ACM, New York, NY, USA, 125-138. DOI=10.1145/504282.504292 http://doi.acm.org/10.1145/504282.504292

[2] Godmar Back and Wilson C. Hsieh. 2005. The KaffeOS Java runtime system. ACM Trans. Program. Lang. Syst. 27, 4 (July 2005), 583-630. DOI=10.1145/1075382.1075383 http://doi.acm.org/10.1145/1075382.1075383

Aaron Boodman

unread,
Aug 28, 2012, 11:27:57 AM8/28/12
to Scott Fujan, PhistucK, Yoyo Zhou, Chromium-extensions, Benjamin Kalman, Matt Perry
On Tue, Aug 28, 2012 at 8:18 AM, Scott Fujan <sc...@fujan.name> wrote:
>> So a basic, typical skeleton for using the alarms API would be:
>>
>> chrome.runtime.onInstalled.addListener(function() {
>> chrome.alarms.create(...);
>> });
>>
>> chrome.alarms.onAlarm.addListener(function(alarm) {
>> ...
>> });
>
>
> Is chrome.runtime.onInstalled the appropriate event? It seems like this
> would work the first time, but then fail the next time the browser started
> -- maybe events are persistent?

Chrome persists what events an extension is interested in. But you
still need to associate the event with a handler each time the event
page loads.

For the special case of onInstalled, we always send the event to the
extension (otherwise there'd be no way to indicate interest because
the event page is never loaded prior to onInstalled).

Alarms are similarly persistent. In general, we updated all the APIs
through which you can make some kind of state change to the browser
(context menus, browser actions, etc) to be persistent.

> Also, I notice chrome.runtime.onStartup (This would be more appropriate?) is
> defined for the dev documentation, but is missing from the beta
> documentation. Is Chrome 23 the first version for which onStartup is
> available?

This API has not been backported to Chrome 22, but it should be. I
will file a bug. I think it will be much more typical to use
onInstalled though, since almost everything you'd want to do in
onStartup is persisted across browser sessions.

- a

Aaron Boodman

unread,
Aug 28, 2012, 1:40:10 PM8/28/12
to Godmar Back, chromium-extensions, Benjamin Kalman, Matt Perry, Yoyo Zhou
On Tue, Aug 28, 2012 at 8:22 AM, Godmar Back <god...@gmail.com> wrote:
>
> I'd like to add another few considerations to better understand your
> thinking.
>
> First, where global state is required - such as for user preferences or
> other configuration information, keeping it in a JavaScript object should be
> more efficient than keeping it in your new storage facility, by definition.

I'm going to need a more concrete example. I don't understand what
you're getting at.

> Plus, having it in memory makes it easier to use it as, say, the angular
> model for a user preferences/configuration page.
> So the true source of the overhead you're fighting is not the global state
> the extension must keep - provided it's written without significant memory
> leaks, it's the v8 state needed to hold these (few, and necessary),
> JavaScript objects. Is that correct?

There's also the memory consumed by WebKit, Chrome, other C++
libraries, as well as the base OS overhead of a process.

> Second, since communication between content scripts and the background page
> is so awkward, many extensions probably will reinject large parts of their
> codebase into the content script side. That's what we do, at least. This
> includes our inheritance framework, all utility classes, etc. etc. This code
> (and it's v8-compiled version) exists in every tab process, and an identical
> copy of it exists also in the background process, which uses the same
> codebase.

It's dangerous to generalize from one data point. A large proportion
of extensions in the store don't have a single content script, as an
example.

> Taken together, I'm wondering if a better way to reduce the overall memory
> consumption of Chrome - all Chrome processes - wouldn't have been to enhance
> v8 to support under-the-hood, MVM- or KaffeOS-style [1,2] sharing of
> internal v8 data structures and, in particular, loaded source code and
> just-in-time compiled code - at least in cases where the code does not
> access its closure, which is true for much generic utility code. That is,
> the code accesses only its parameters, and the just-in-time compiled native
> code is the same in every process. It could be shared in the same way
> read-only .so shared libraries are shared. Has this been/is this being
> considered? It could, potentially, reduce the per-instance overhead for all
> v8 processes, shrinking extension processes in the process, and make the
> need to have ephemeral background page processes much less urgent.

We have definitely considered approaches like this. However they would
not help with the memory used by WebKit or Chrome, which is
significant. And they would be quite a bit more work, and a riskier
project than event pages.

> One last thought: doesn't not having background processes (significantly)
> increase the latency when a popup is opened? I know for our extension, we
> would be pulling in a large amount of code - and asking v8 to compile it -
> every time the user invoked a browser action.

It could. Perhaps you should try pulling in less code :). Have you
seen this awesome new framework: http://vanilla-js.com/!?

Anyway, event pages are optional. If you find that it results in your
extension being less responsive than you like, you're free to not use
them. You'll just miss out on this opportunity for being featured in
the store. We plan to do this with all major new features though, so
you'll have another shot.

We may try to encourage event pages more strenuously in the future,
but it's going to depend on how successful they are I suppose. And we
don't have any plans along those lines today.

- a

PhistucK

unread,
Aug 28, 2012, 1:47:12 PM8/28/12
to Aaron Boodman, Godmar Back, chromium-extensions, Benjamin Kalman, Matt Perry, Yoyo Zhou
Hehe. I like that! :P
I always preferred that.
 
Anyway, event pages are optional. If you find that it results in your
extension being less responsive than you like, you're free to not use
them. You'll just miss out on this opportunity for being featured in
the store. We plan to do this with all major new features though, so
you'll have another shot.

We may try to encourage event pages more strenuously in the future,
but it's going to depend on how successful they are I suppose. And we
don't have any plans along those lines today.

- a

Godmar Back

unread,
Aug 28, 2012, 9:02:43 PM8/28/12
to Aaron Boodman, chromium-extensions, Benjamin Kalman, Matt Perry, Yoyo Zhou
On Tue, Aug 28, 2012 at 1:40 PM, Aaron Boodman <a...@chromium.org> wrote:
>
> We have definitely considered approaches like this. However they would
> not help with the memory used by WebKit or Chrome, which is
> significant.

That's exactly why you need to cut down there. There should be almost
no memory consumption for the WebKit parts if you have an empty
background page DOM, and all code should be shared (via the OS). Any
improvement there would automatically benefit extension processes and
renderers. OS base overhead is actually quite low.

> And they would be quite a bit more work, and a riskier
> project than event pages.

No doubt.

To add a philosophical point/observation. Traditionally, OSs provide
abstractions that give programs illusions - that they have a dedicated
CPU (processor -> process), that they have exclusive access to the
entire memory (a linear virtual address space whose content persist
while the process runs), that they have dedicated I/O units
(stdin/stdout). This model has been extremely successful and greatly
simplified programming over the last 40 years.

With ideas like event pages (and related, the approach used in Android
which effectively hides the process abstraction from programmers),
these conveniences are rolled back - programmers now have to be aware
when their program is loaded/unloaded and adapt accordingly. That's a
step back, or least reminiscent of, the model used in the 1960s before
the advent of time-sharing and virtual machine machines. That's
despite the fact that even today's mobile devices are more powerful
than the mainframes from that era.

So it'll be interesting to see how this turns out.

- Godmar

Adam Barth

unread,
Aug 28, 2012, 9:23:00 PM8/28/12
to Godmar Back, Aaron Boodman, chromium-extensions, Benjamin Kalman, Matt Perry, Yoyo Zhou
On Tue, Aug 28, 2012 at 6:02 PM, Godmar Back <god...@gmail.com> wrote:
> On Tue, Aug 28, 2012 at 1:40 PM, Aaron Boodman <a...@chromium.org> wrote:
>> We have definitely considered approaches like this. However they would
>> not help with the memory used by WebKit or Chrome, which is
>> significant.
>
> That's exactly why you need to cut down there. There should be almost
> no memory consumption for the WebKit parts if you have an empty
> background page DOM, and all code should be shared (via the OS). Any
> improvement there would automatically benefit extension processes and
> renderers. OS base overhead is actually quite low.

That's certainly an ideal and something we're working towards in
parallel with this effort. As with many engineering tasks, however,
it's not as easy as it sounds. :)

Adam

PhistucK

unread,
Sep 5, 2012, 12:48:04 PM9/5/12
to iron2000, chromium-...@chromium.org, Benjamin Kalman, Matt Perry, Yoyo Zhou
I did not read everything, but I will just mention chrome.runtime.onStartup and chrome.runtime.onInstalled -
onStartup is not there yet, but it is there on dev/canary releases - which currently correspond to Chrome 23.

The dev/canary documentation is here -


PhistucK



On Wed, Sep 5, 2012 at 4:33 PM, iron2000 <bland...@gmail.com> wrote:
Maybe it will appeal to more if there is an event for "on extension first load/on Chrome browser start" or "on Chrome browser close".

I'm playing around with an undo close tab extension where there is an option to save closed tabs after browser close.
If the option is disabled the closed tab data is cleared on browser start, specifically when the background page loads via the DOMContentLoaded event.

But if I switch to event pages, the DOMContentLoaded event will be triggered everytime the event page loads thus clearing the closed tab data every time instead of once either on browser start or browser close.
Or I should stick with persistant background pages?

I'm still very new to Javascript (but I'm trained in Java).

On Tuesday, 28 August 2012 04:33:37 UTC+8, Aaron Boodman wrote:
Hello extension developers!

In Chrome 22, we’re releasing two new APIs that we hope you’ll use to kill off your memory-guzzling background pages:

  • Event pages are a replacement for background pages. They are similar to background pages, except that they are automatically destroyed by the system when idle, and brought back to life when needed. Converting to event pages is usually really easy, and will improve Chrome’s performance and responsiveness -- especially on lower-power devices.
  • The Storage API is a replacement for HTML5’s localStorage, but with a couple big advantages. The Storage API can be used within content scripts directly, without having to send messages to a background page. This should allow many extensions to completely remove their background pages. The Storage API also has built-in support for synchronization. Any data stored within the sync namespace is automatically replicated to each device the user has your extension installed on.

To add some extra incentive, we’ll be featuring the awesomest extensions that kill their background pages using either of these APIs in the Chrome Web Store. Featured extensions periodically show up at the top of the extensions category, with gigantic promotional images that are pretty much impossible to miss. We'll also be selecting a few of these extensions to showcase in an upcoming blog post. To be eligible, just upload your converted, background-page-free extension to the Chrome Web Store by October 1.

Note that both these new APIs require manifest version 2. We plan to require manifest v2 for updates to all existing extensions starting in Chrome 23, so this is a good thing to start looking at now anyway.

So get out your editor and a scalpel, and let us know how these APIs work for you. If you have any questions, just reply to this message, or start a new thread on the mailing list.

Happy hacking,

- Ben (storage), Matt (event pages), Yoyo (event pages), and Aaron (overhead)

--
You received this message because you are subscribed to the Google Groups "Chromium-extensions" group.

iron2000

unread,
Sep 6, 2012, 10:50:36 AM9/6/12
to chromium-...@chromium.org, iron2000, Benjamin Kalman, Matt Perry, Yoyo Zhou
Thanks, chrome.runtime.onStartup seems to be what i'm looking for.

Anyway are there anymore examples for chrome.runtime.getBackgroundPage()?

It has the callback function which makes it different to how the old chrome.extension.getBackgroundPage() can be used.

For example, before I can do "localStorage.settings = JSON.stringify(chrome.extension.getBackgroundPage().settings);".
Now with the callback function for the runtime version I have no idea how to use it.

I got "Uncaught Error: Invocation of form runtime.getBackgroundPage() doesn't match definition runtime.getBackgroundPage(function callback)" so my programming sense tells me I can't just 'switch to chrome.runtime.getBackgroundPage()'.


PhistucK



To unsubscribe from this group, send email to chromium-extensions+unsub...@chromium.org.

PhistucK

unread,
Sep 6, 2012, 12:30:10 PM9/6/12
to iron2000, chromium-...@chromium.org, Benjamin Kalman, Matt Perry, Yoyo Zhou
Assuming an identical state, that should be -
chrome.runtime.getBackgroundPage(
 function (page)
 {
  localStorage.settings = JSON.stringify(page.settings);
 });
Just like the documentation reads -

PhistucK




To post to this group, send email to chromium-...@chromium.org.
To unsubscribe from this group, send email to chromium-extens...@chromium.org.

iron2000

unread,
Sep 6, 2012, 9:04:49 PM9/6/12
to chromium-...@chromium.org, iron2000, Benjamin Kalman, Matt Perry, Yoyo Zhou
Thanks PhistucK!
Now is to spend time with the code.

iron2000

unread,
Sep 11, 2012, 7:37:57 AM9/11/12
to chromium-...@chromium.org, iron2000, Benjamin Kalman, Matt Perry, Yoyo Zhou
Tried the chrome.runtime.onStartup event.
Its what I wanted but it seems to trigger too slow, its not as fast as DOMContentLoaded.

The user can still see the state before the trigger before it actually triggers, which makes it more suited for background stuff.

PhistucK

unread,
Sep 11, 2012, 7:44:05 AM9/11/12
to iron2000, chromium-...@chromium.org, Benjamin Kalman, Matt Perry, Yoyo Zhou
What about something like this?

chrome.runtime.onStartup(
 function ()
 {
  sessionStorage["started"] = 1;
 });

if (!sessionStorage["started"])
{
 doStartupStuff();
}

PhistucK



--
You received this message because you are subscribed to the Google Groups "Chromium-extensions" group.
Message has been deleted

iron2000

unread,
Sep 12, 2012, 12:22:19 PM9/12/12
to chromium-...@chromium.org, iron2000, Benjamin Kalman, Matt Perry, Yoyo Zhou
The time lag between straight using onStartup and using session storage + onStartup is roughly the same.

But for the session storage + onStartup method, the session storage is cleared once the background page goes inactive.
The next time the background page is triggered doStartupStuff() will run again as onStartup() can't be there to set the session storage.
Kind of results in an onSuspend() behaviour.

Joshua Deltener

unread,
Nov 5, 2012, 11:40:19 PM11/5/12
to chromium-...@chromium.org, Benjamin Kalman, Matt Perry, Yoyo Zhou
chrome.storage.local seems to have limits on gets (even with unlimited storage).  Example:  My extension stores feed data and I can save over 2MB to 1 key/value, but I can't fetch anything over ~840k!!?

iron2000

unread,
Nov 27, 2012, 7:15:43 AM11/27/12
to chromium-...@chromium.org, Benjamin Kalman, Matt Perry, Yoyo Zhou
Missed the 1 October date (had to wait till onStartup() hit stable) :P

But all 4 of my extensions are event page enabled.
I wholly support the notion that extensions should unload when not needed to lower memory usage.

Thangaraju Ramasamy

unread,
Sep 21, 2013, 6:02:03 PM9/21/13
to chromium-...@chromium.org, Benjamin Kalman, Matt Perry, Yoyo Zhou
I am using background page to play audio shoutcast streams using <object> tags, and popup page is used to show the channels and controls.

Does Event page help to play this?  


Thanks
Thangaraju 
Reply all
Reply to author
Forward
0 new messages