Tab shutdown and onUnload spinloop
We have a bug that tabs sometimes can take too long to close, where (as generally in Chrome-land) "too long" is defined as "more than instantly".
The common culprit in slow tab shutdown is onUnload
handlers. These
allow pages to do something as they're being shut down (more on what
that exactly means later). We can only start the handler after the
user has indicated it's time to close the tab, so pretty much any time
they take is too much. If we're especially unlucky it can take a
rather long time, as running the page JS requires potentially swapping
back in the tab process.
One performance improvement that was done in this area was to track,
for each tab, whether the page JavaScript registers an onUnload
handler at all; if it doesn't, we can just kill the tab process
immediately rather than doing the IPCs to tell the page JS to run.
Another tweak was to change the "tab is hung, do you want to kill it?"
monitor to be much more aggressive when we're in the process of
shutting down a tab. Ojan tells me we have it at a second. But that
doesn't help you when you click a link — the onUnload
handler still
runs, but we can't put the hang checker in aggressive shutdown mode.
The interesting meta-question is: why does this API even exist? I asked some JavaScript hacker friends and they had two broad reasons. One, you use it to clean up memory leaks in IE (IE can't GC circular references between JS and the DOM, so you break the reference cycles when "shutting down"). But in general, they explained, the more common application is from people who don't know better.
Because when you're shutting down, any asynchronous operation you
begin isn't guaranteed to complete (pinging a server to release a
lock, for example — Google Docs does (did?) this). The browser
cancels all your outstanding requests when your page is killed, so
there's a race between your onUnload
ping going out and the page
getting cancelled.
Which takes us back to the original bug. I heard today that some ad networks, which (I imagine) want to track "how long" a user was on the page, also ran into this shutdown racing problem. Their "fix": start the ping, then run a JS loop that spins for half a second or so, blocking shutdown. From their perspective, as soon as their handler returns, the page may shut down, so the only way to keep their page up long enough for the ping to go through is to spin.
Worse, some pages have multiple ads from the same network! Comment 64
on the bug mentions one where three separate ads that each serially
spin for 200ms on shutdown. Sadly, this affects all browsers and
sucks for everyone. Probably the proper fix is to work with browser
vendors on a better API (see also the disasterous <a ping=...>
discussion, which is almost exactly the same problem, but politically
unpopular with users who don't understand the consequences).