It feels like at least some of the components you're referring to could not realistically be (a / separate) webextension(s) as a result of their needing to be "in sync".At the end of the day, I believe we should end up in a world where most of the Firefox frontend is made available via system addons and glued together using well-defined API surfaces. What would it be like to have our tabbed browser, location bar, search interface, bookmarks system, session restore, etc be independently hackable? It would be awesome! It would mean a higher quality product, with more opportunities for volunteer contributors to improve specific areas. It would likely mean reduced edit/build/run/test cycles. It might even give addon authors the ability to completely replace certain components of the browser if they so choose.
_______________________________________________ firefox-dev mailing list firef...@mozilla.org https://mail.mozilla.org/listinfo/firefox-dev
What isn't clear to me is where exactly do we draw the line for API support? It's cool to say that awesomebar, bookmarks, session store, etc are loosely coupled and independently hackable - this sounds great from an ivory tower. But the cobweb of inter-dependencies between all these components exists for a reason: it was/is necessary to implement features.
I think Benjamin’s first point that swiftly attempts to validate the assumption that the core limiting factor is in fact the modularity and module boundaries in our codebase is comparing apples to oranges by offsetting process against code architecture.I think we’re looking for a problem that presumably causes our apparent inability to go faster in the wrong area.In that vein I was very pleased with Richard Newman’s post to this thread; you should read it!
Before I start, I’d like to point out that our current WebExtensions model is mostly comprised of interfacing with our lower level JS modules, adding a layer of indirection that we most often don’t need in frontend code that builds the browser.
On Fri, Oct 7, 2016 at 2:48 PM, Gregory Szorc <g...@mozilla.com> wrote:
> 3) If we're talking about a significant change of architecture to the
> Firefox frontend and the high costs associated with that change, I'll throw
> out an alternative idea: (re)write the frontend in a typed language like
> Rust. I argue that a typed language - and Rust especially - would deliver
> "well-defined, documented, and enforced module boundaries or interfaces"
> better than JavaScript ever will.
+1. I think we should probably stick with HTML/JS/CSS for basic UI
stuff like layout, setting up button events, DOM manipulation etc, but
a lot of the code we have in JSMs right now would be much safer to
implement in Rust, and most likely faster.
> 4) I have significant concerns about the concept of system add-ons.
> Currently, the composition of Firefox (in terms of code) is essentially
> deterministic from the commit in mozilla-central it was built from. We know
> exactly what Firefox code is running (OK, /should/ be running) on users'
> machines. System add-ons fundamentally change that from ~1 combination of
> software components to N, where N could be absurdly large (10^3 or larger).
> It is hard enough to track down intermittent failures in test automation
> with a well-defined software configuration. System add-ons introduce whole
> new classes of bugs related to how different versions of add-ons interact
> with each other. They require more and more complicated testing
> infrastructure to test various combinations of add-ons. This makes assuring
> quality harder. System add-ons seem like they add cost to the release
> process and undermine stability (even if they may make writing code easier -
> but software development is about a whole lifecycle, not just writing the
> code).
I think we're largely in agreement overall (see my earlier post on
this thread), but just to help assuage any concerns about our current
use of system add-ons - we require all extensions that ship with
Firefox to be in-tree, and any out-of-cycle updates should be landed
on the appropriate branches. So, they live alongside other code in
Firefox, are tested as part of the usual automation and QA, etc.
We do have the ability to push arbitrary updates, but we only use
those for hotfix-style activities, similar to the current hotfix.
Any out-of-cycle updates pushed "expire" when the next regular
application update happens.
I agree. I think our problem is that hacking on Firefox is
exceptionally hard, and testing+shipping it is too. I don't think
either of things are hard because there aren't good enough boundaries
between different components.
Pushing updates quickly to just omni.jar and allowing restartless
updates is basically equivalent to moving features to extensions and
updating them that way. It just so happens that today it's easier for
a new team to get going by hacking on an add-on, it's faster and safer
for us to ship these standalone rather than update the whole of
Firefox, and extensions already provide a way to do restartless
install+update.
I don't think it follows that therefore everyone must develop on
extensions and all updates should be done the way extensions are. We
can and should make Firefox easier to hack on and should make shipping
faster + safer.
Brendan Barnwell's answer touches a very important point, IMO.
Here's a question for discussion:
Why choose firefox over chrome?
Firefox is slightly slower than chrome; specially in a computer
with really high amount of RAM available.
If a tab crashes in Firefox, the whole Firefox crashes (in current
stable). If a tab crashes in chrome, only that tab suffers (until
you hit the 20's and beyond) so you, usually, can just continue
working afterwards.
Chrome's v8 is faster in more tests than Firefox's SpiderMonkey
than the other way around.
Chrome's interface seems to be the one inspiring Firefox's. At
least, for the most part.
Chrome has a more useful developer tools toolset for least used
features (E.g. inline svg)
Chrome supports more standards than Firefox (Firefox is in s
struggle to implement them).
Both are free of charge.
...But then... With those and more... Why sticking to Firefox?
Firefox allows extensions to have superb power! With extensions, my firefox instance becomes "my browser". Heck just look at my profile! I have (jump to the end of the list when you get the idea):
Is Firefox kinda slow? YES! Heck, it is even using ~1.2GB of ram most of the time and some page loads could be ~0.5s faster. It's worth it!!!
Could these extensions be made in WebExtensions? Heck no! Chrome
never lets an extension touch Storage stuff. Forget them being
protected with a password!
Colored tabs in WebExtensions? Pff... Who wants that, right? Tell
that to the +200K users of a featured addon!
Metadata in stored passwords? Boom! Featured addon!
(https://addons.mozilla.org/en-GB/firefox/addon/password-categories/)
WebExtensions is not ready for any of this on Chrome. For the time it has been like this, I don't think it will ever be.
In the late years, for many feature requests I have been directly
or indirectly bombarded with "If you want feature X, do it
yourself or get an addon for it". So far that can be true because
the "legacy" extensions can do just about anything.
Now imagine this happened instead:
- I had an addon on my browser that colors tabs based on the
website name and a heuristic of the colors mix in the first page
it finds. The browser now only supports WebExtensions. How do I
update it so it works on my browser?
- You can't. We now do not support extensions that change the
browser UI in any way except for adding a button.
Think as a user now. How do you react? You had an addon you could use and worked, now you cannot have and you can't even expect it to ever work on your browser. EVER!
I think that WebExtensions is a very good tool for the majority
of the extensions. It has a very direct API for use and simplifies
the code complexity when you just want a small purposed extension
that does changes to a web page, potentially with some extras.
We do still need that low level API, though. The one that allows
changing the shape of the tabs, place the tabs on the left side of
the browser window, change the color of the tabs, add toobars,
access about:config configs...
I believe, with both API made in a correct fashion, most extensions will be WebExtensions. Only slightly less safe than a web page (but requires explicit permissions) and cannot do harm without warning. Reviewing those extensions should be a much easier task than the other extensions. The API (already in nightly) to communicate between WebExtensions and "legacy extensions" can be a huge thing here!
While having this e-mail sitting here, I thought:
AFAIK, WebExtensions are limitless when acting inside a web page
(I'm relating to content scripts). They have the same power as the
legacy extensions.
It is on the background pages that WebExtensions are limited
which is exactly when they need to act on the browser itself and
do the awesome (such as coloring the tabs or opening a popup that
clearly belongs to the browser and not just a web page).
How about this:
Make 3 code groups:
1 can only communicate with 2, 2 can communicate with either 1 or
3, 3 can only communicate with 2, 2 and 3 can only share data
using the message API (for consistency).
3 is not protected behind a tight permissions system like
WebExtensions but it must specify the components it accesses in
the manifest file (security). The components requested (as a
key:value) are included in a global object since the start of the
script.
The scripts for 3 may only be used for features that do not exist
in WebExtensions (guaranteed by the manual review and, possibly,
to certain extent by the automatic reviewer).
This should ease extension reviewing, keeping compatibility with
other browsers (all that works in chrome works here) and stick the
tongue out to chrome when you have colored tabs and chrome can't.
Thoughts?
I have a couple of thoughts on this, on three lines:
XPCOM. We did have extensive contracts and interfaces, strictly typed and all. My take on the downsides is that we struggled to create future-proof APIs for one. Also, the implementations of those had undocumented ranges, bugs, and side effects that callers depended upon. And some of our APIs never carried fruit.
I also think that tight locking between components isn't as much about the API between them, but how much of the API surface is relied upon.
I wonder how other folks see our storyline to deCOM, and how we'd
modularize without the same problem.
WebExtension compat. If we start exposing internals of Firefox
needed for Firefox development, we'll fork the API space of
WebExtensions. If more browser vendors do so, we'll get into a
game of webcompat for WebExtensions. Not sure if that's helpful
for the extension ecosystem.
devtools. You quoted devtools as a success story for developing quickly, and I'd actually say the contrary. We had several years of experience with js debuggers and debugging, and only then were able to create an API that was somewhat stable. And even then, IIRC the entry of FxOS and Android and Chrome debugging still opened a bunch of challenges. In that sense, I think devtools is a great example that you can't create good APIs quickly. You need a lot of experience in the field you're tackling, and then you can start defining good APIs, and even those still evolve.
Axel
I agree. I think our problem is that hacking on Firefox is
exceptionally hard, and testing+shipping it is too. I don't think
either of things are hard because there aren't good enough boundaries
between different components.
I agree with Benjamin here.
Simple bugs cannot be fixed easily because of gazillions of unexpected
dependencies. … Having clearer boundaries inside our own code is critical, too.
On 10/10/16 22:44, Richard Newman wrote:
> So yes, clearer boundaries — but they should probably not be the
> boundaries we have now.
Would Firefox then be a very basic "core" browser, implemented in
HTML/CSS/JS, with extensions for adding features on top of this
("awesomebar", bookmarks, devtools, etc?) If so then the "core"
browser needs to implement WebExt APIs for each feature to use,
possibly with a "mozilla-only" permission if it's something we
wouldn't want third-party extensions to be able to do?
I've watched the presentation of github and facebook doing GraphQL at https://www.youtube.com/watch?v=wPPFhcqGcvk with interest.
In a similar vein to what Richard is saying, they're moving the api boundary from what the service provider can offer to what the client needs.
Also, this isn't new to mozilla, per se. http://www-archive.mozilla.org/rdf/doc/aurora.html, just to scare folks.
Axel
IMO it's a mistake to treat all interfaces as equal and public, which seems to be the point of the WE side of this discussion.
We are shipping these *today*, and shipping is a tedious and fairly high-risk process because we don't have modular isolation or testing.
But let's say that atomic sync is something that we believe is important: I believe we *have to* spend the time to reorganize the system so that sync as a module that stores passwords, bookmarks, etc is lower/more basic in our module structure, and then we build our bookmarks UI, location bar, etc, on top of that core structure. We are in charge of designing these things.
Thank you all for the beginnings of a great discussion!I'd like to follow up on a few points which I think were misunderstood.
- The focus of my post is about requiring good module boundaries for code that wants to move quickly, and the notion that WebExtensions are the right way to do that. Although I like indulging in talk about making the entire browser modular, that is clearly not something we can accomplish soon. I am talking about the pipeline of development that we're building which starts out with test pilot, through SHIELD studies, to system addons. We are shipping these *today*, and shipping is a tedious and fairly high-risk process because we don't have modular isolation or testing.
- I also don't think we should limit ourself to WebExtensions as they are today. WebExtensions are purely asynchronous today because of design decisions that Chrome made and we also accept that addons shouldn't be allowed to block the browser UI. That doesn't mean that we can't make API surfaces which are synchronous/blocking, if we feel that's the right tradeoff.
- We can make choices about the "stability" of API surface: both APIs we're building internally, and even APIs we expose to addons. I'm going to follow up separately about what I think we should have learned from XPCOM, but if there's anything we should learn it's that frozen API surfaces are often the wrong choice.
I agree that for problem statements that like constrained modularity, building that modularity out and building upon it is going to help the software development process.We have a stated desire to let certain teams move much more quickly. This includes Hello in the past, it includes a bunch of test pilot and shield studies now, and it will include activity stream work in the future. What I was trying to point out, with a long history of academic research, is that there is a "physics" of software engineering that we cannot avoid: projects and teams move faster when there are fewer modular entanglements, smaller modules in general. We can train new employees and attract new contributors better with smaller boundaries around the code that they have to understand to be productive, and better documentation aout where the boundaries are.
Richard is right that if we try to "remodularize" around our existing infrastructure, some things are going to be really hard. It's basically impossible to provide atomic sync with things designed the way they are. But let's say that atomic sync is something that we believe is important: I believe we *have to* spend the time to reorganize the system so that sync as a module that stores passwords, bookmarks, etc is lower/more basic in our module structure, and then we build our bookmarks UI, location bar, etc, on top of that core structure. We are in charge of designing these things.
We always *have* a structure. I believe that currently we have a structure where Firefox is a large monolith which is very difficult to change effectively. To change that, we don't need to and shouldn't rewrite it all. But we should start carving off pieces so that they are smaller and have real boundaries. I believe we should start with the things which are trying to move faster right now. Maybe we should also start at the other end with core infrastructure like sync. If we carefully carve off pieces, keeping a longer-term vision in mind, we will end up in a place where there either is no monolithic center, or we carved it down enough that we can document/understand/hack on it more easily.
--BDS
On Thu, Oct 6, 2016 at 11:08 AM, Benjamin Smedberg <benj...@smedbergs.us> wrote:
--BDSI spent a week writing a thing about modularity, webextensions, and going faster. I think it's important for us to decide the module structure of our code especially as we start shipping independent modules/going faster. And I believe that having better module structure, boundaries, and documentation is critical to our teams being more agile and also attracting contributors to the project.
http://benjamin.smedbergs.us/blog/2016-09-03/modularity-and-webextensions/
In the post I asked everyone to send followups to firefox-dev, so I wanted to start a thread here to collect responses. Over the next months I'd like this to turn into a firm decision about how we're going to build system addons; but I'd like to start by seeing what feedback people have and even whether I've framed the problem correctly.
I personally think that we should double down on WebExtensions as a model and start using that for large parts of Firefox. But Andy McKay and Rob Helper had some good counter-thoughts and I've asked them to post here to elaborate.
3) If we're talking about a significant change of architecture to the Firefox frontend and the high costs associated with that change, I'll throw out an alternative idea: (re)write the frontend in a typed language like Rust. I argue that a typed language - and Rust especially - would deliver "well-defined, documented, and enforced module boundaries or interfaces" better than JavaScript ever will.
+1. I think we should probably stick with HTML/JS/CSS for basic UI
stuff like layout, setting up button events, DOM manipulation etc, but
a lot of the code we have in JSMs right now would be much safer to
implement in Rust, and most likely faster.
4) I have significant concerns about the concept of system add-ons. Currently, the composition of Firefox (in terms of code) is essentially deterministic from the commit in mozilla-central it was built from. We know exactly what Firefox code is running (OK, /should/ be running) on users' machines. System add-ons fundamentally change that from ~1 combination of software components to N, where N could be absurdly large (10^3 or larger). It is hard enough to track down intermittent failures in test automation with a well-defined software configuration. System add-ons introduce whole new classes of bugs related to how different versions of add-ons interact with each other.
Here are my thoughts. Hopefully I'm not repeating other people here!
-Mike
As a side note, it still surprises me that most JS projects (front-end or Node) don't use the Typescript (or flow) compiler. It just takes running it on normal JS code to have errors reported for free with no consequence; errors that are not reported by any other tool.
Or, to take rnewman's angle here, is there an opportunity here to draw some new boundary lines and define a new (but small) WebExtension Thing that combines capabilities from several of our current modules for great good?
- XPCOM / XPIDL, for better or worse, offered a boundary and interface system. I think those interfaces were originally intended to be pretty stable. Down the line, I seem to recall us deciding that having frozen interfaces there was slowing us down, and so now those interfaces are changed at will. I understand that we were more constrained because more applications were relying on the underlying interfaces, but this all starts to feel kinda familiar. Are we at risk of creating a new set of interfaces and silos that get holes poked through them over time because they slow us down instead of speeding us up? Are we repeating ourselves? If so, what did we learn last time that will make this time better?
I agree with having one type of border between internal and external code instead of many. I would also be happy to have only 1 border between different bits of internal code, though I think that's difficult in practice, mostly because you end up with several abstraction levels (if we keep using HTML-like things for frontend, how do you keep CSS for different "modules" separate and isn't that really a different boundary from the boundaries between your JS, etc.)We do have some boundaries with XPCOM, some others with JSM, yet some others with message managers.
But that's just too many different kind of boundaries/interfaces. If we only had one border, everything would have been much better.
If you look, again, at session restore you will have to go through all of them and it is far from being obvious and will feel very hard to approach to anyone except mozilla employees who have to learn all these things. Web extension abstracts all that. The difference between a content script and a background page is very small.
- Is there a browser component that we can experiment with, and attempt re-implementing with the WebExtension API to see how it feels? Or, to take rnewman's angle here, is there an opportunity here to draw some new boundary lines and define a new (but small) WebExtension Thing that combines capabilities from several of our current modules for great good?
... but then, is avoiding the UI problem really going to be helpful in the future? How do we transition the experience from a hypothetical successful session restore add-on to other frontend features if we haven't solved that problem? And, most negatively, how do we avoid that becoming boundary type number N + 1 (after XPCOM, JSM, XBL, message managers, system add-ons, ...) that we then don't get rid of and have to teach every contributor (employee or volunteer)?The big advantage to this particular feature is that it doesn't involve much UI, which is where WebExtension is the most limited.
- It might be worth considering re-implementing some browser components using WebExtensions. This would likely involve adding new, probably privileged APIs.
- XPCOM / XPIDL, for better or worse, offered a boundary and interface system. I think those interfaces were originally intended to be pretty stable. Down the line, I seem to recall us deciding that having frozen interfaces there was slowing us down, and so now those interfaces are changed at will. I understand that we were more constrained because more applications were relying on the underlying interfaces, but this all starts to feel kinda familiar. Are we at risk of creating a new set of interfaces and silos that get holes poked through them over time because they slow us down instead of speeding us up? Are we repeating ourselves? If so, what did we learn last time that will make this time better?
- Is there a browser component that we can experiment with, and attempt re-implementing with the WebExtension API to see how it feels? Or, to take rnewman's angle here, is there an opportunity here to draw some new boundary lines and define a new (but small) WebExtension Thing that combines capabilities from several of our current modules for great good?
... but then, is avoiding the UI problem really going to be helpful in the future? How do we transition the experience from a hypothetical successful session restore add-on to other frontend features if we haven't solved that problem? And, most negatively, how do we avoid that becoming boundary type number N + 1 (after XPCOM, JSM, XBL, message managers, system add-ons, ...) that we then don't get rid of and have to teach every contributor (employee or volunteer)?If you look, again, at session restore you will have to go through all of them and it is far from being obvious and will feel very hard to approach to anyone except mozilla employees who have to learn all these things. Web extension abstracts all that. The difference between a content script and a background page is very small.
- Is there a browser component that we can experiment with, and attempt re-implementing with the WebExtension API to see how it feels? Or, to take rnewman's angle here, is there an opportunity here to draw some new boundary lines and define a new (but small) WebExtension Thing that combines capabilities from several of our current modules for great good?
The big advantage to this particular feature is that it doesn't involve much UI, which is where WebExtension is the most limited.
- The focus of my post is about requiring good module boundaries for code that wants to move quickly, and the notion that WebExtensions are the right way to do that. Although I like indulging in talk about making the entire browser modular, that is clearly not something we can accomplish soon. I am talking about the pipeline of development that we're building which starts out with test pilot, through SHIELD studies, to system addons. We are shipping these *today*, and shipping is a tedious and fairly high-risk process because we don't have modular isolation or testing.
- XPCOM / XPIDL, for better or worse, offered a boundary and interface system. I think those interfaces were originally intended to be pretty stable. Down the line, I seem to recall us deciding that having frozen interfaces there was slowing us down, and so now those interfaces are changed at will. I understand that we were more constrained because more applications were relying on the underlying interfaces, but this all starts to feel kinda familiar. Are we at risk of creating a new set of interfaces and silos that get holes poked through them over time because they slow us down instead of speeding us up? Are we repeating ourselves? If so, what did we learn last time that will make this time better?
We do have some boundaries with XPCOM, some others with JSM, yet some others with message managers.
But that's just too many different kind of boundaries/interfaces. If we only had one border, everything would have been much better.
If you look, again, at session restore you will have to go through all of them and it is far from being obvious and will feel very hard to approach to anyone except mozilla employees who have to learn all these things. Web extension abstracts all that. The difference between a content script and a background page is very small.
I have to disagree on this.
XPCOM boundaries are per-instance boundaries, JSM is more-clearly-than-xpcom service boundaries, message managers are on-change notification boundaries.
Those things are just realities in software design, and need to be reflected.
I think it's an element of good software architecture that the difference between these three concepts manifests in the APIs in which you interact with them.
Axel
IMHO, React makes a lot of statements that are very related to the statements that XUL made 15 years ago.
The core statement might be "HTML can't fly". Back then, mozilla's answer was XML. Facebook's answer today is javascript.
The impact on HTML of both is the same though, it constrains HTML from winning.
Axel
2016-10-12 8:26 GMT-07:00 Gijs Kruitbosch <gijskru...@gmail.com>:... but then, is avoiding the UI problem really going to be helpful in the future?The big advantage to this particular feature is that it doesn't involve much UI, which is where WebExtension is the most limited.
Aligning ourselves with the web is a good goal, IMO, but seems problematic with WebExtensions. WebExtensions, its async-ness, and its lacking support for actual UI creation, and interfacing with related UI on a single main thread with multiple async components, is (to the best of my knowledge) not a solved problem**. Then there's all the stuff about exposed vs. internally used API surfaces. Using React for the internal implementation of the frontend components would be better-understood (even if I'm personally not a massive React fan...).
Those are all solvable problems, but there would need to be a commitment that people want to invest in this, and broader agreement on tools and direction.