Electrolysis/Extension Compatibility

From MozillaWiki
Jump to: navigation, search

Making Firefox use content processes will affect extension compatibility. Since extensions are important to our users, we need to identify how to mitigate this impact.

The core technologies which we want extension authors to use include:

  • Jetpack (the jetpack API design is compatible with asynchronous calls to content)
  • The message manager. This is a message-passing interface which works in Firefox 4 and allows code to be written which is compatible with a single or multiple processes.

Extensions which touch content without the message manager or jetpack would not work without compatibility APIs. There are currently several different ways:

  • directly through <browser>.contentDocument and <browser>.contentWindow
  • indirectly through DOM events which propagate from content into chrome event handlers with a .target
  • indirectly through the loadgroup/docshell assoiated with a network load (nsIChannel)
  • indirectly through content policy implementations
  • other access (long tail/unknown)

Here are some options which have been proposed:

Disable Content Processes

Disable content processes for extensions which are broken until they can be ported. This could be managed with a install manifest flag, similar to <em:unpack> in Firefox 4.

Rewrite Popular Extensions

Spend Firefox engineering time porting (or helping to port/review) the top N extensions to use the message manager. This is what the mobile team did for Adblock Plus.

Wrappers

The most invasive compatibility change would be to implement a wrapper so that extensions could continue to synchronously access content objects. The basic wrapper code is already available (CPOWs), but there are many different degrees of compatibility which affect the amount of engineering time, risk, and actual extension compatibility.

The fundamental disadvantage of a synchronous wrapper is that it allows the Firefox UI to become blocked on content, which can negate the benefits of the content process.

In terms of implementation, any synchronous call will require some significant auditing and rewriting of the existing process implementation: synchronous calls mean that IPDL messages can be delivered in surprising orders within nested event loops. Either the IPDL layer or the client code (networking and others) will require auditing and fixing. This is risky because the bugs would only surface intermittently and only when using these wrappers.

Because it is easy to leak permanently with cross-process cycles, we have a rule in place that content may not hold a reference to chrome objects. This means that some patterns that extensions use may still not work, even with wrappers. e.g.

browser.contentDocument.someFunction = function() {
  /* extension function added to the window object here */ }
}

This limitation could be solved by implementing a cross-process cycle collector, but that would be a very significant project.

There are ways to mitigate some of the responsiveness hits of synchronous wrappers by delaying the initial call into content until the content process is known ready to process it, but then operating synchronously: this allows the code to wait for the content event loop to "wake up". It is an intermediate solution between the message manager and direct access to browser.contentWindow, because it allows using a closure function:

browser.runAsyncInWindow(function(win) {
  /* access win.document and other content DOM synchronously here */
}

DOM event propagation

Extensions which rely on DOM events propagating from content through chrome are very hard to fix with a compatibility layer: when extensions install a chrome event listener, we don't know whether they intend to listen for chrome or content events. And it is entirely impractical for performance reasons to forward every possible event (even filtering only those which have an event listener installed). We are actually planning on fixing (breaking) this propagation model well before content processes, but it is something to keep in mind.

Access through network channels or content policy

Extensions which implement the current content policy API, cannot possibly work correctly without changes. bz and bsmedberg are working on a redesigned content policy API, and believe we know the extensions which implement it.

Extensions which install HTTP listeners which also access content will need to be redesigned. There is no effective compatibility layer that we can think of. Fortunately this is fairly rare and those advanced extensions which do it (adblock) appear to be maintained.