Tuesday , January 19 2021

The Firefox UI Is Now Built with Web Components, Hacker News


A couple of weeks ago, we landed acommitthat took years of effort at Mozilla. It removed “XBL”, which means we’ve completed the process of migrating the Firefox UI to Web Components. It wasn’t easy – but I’ll get to that later.

The Firefox UI can be thought of as a very large single page app. It was built with DOM and JS from the start, which was a bold technology choice for a native application 20 years ago. Because of this, Mozilla implemented some features necessary to build complex web applications way before the Web platform supported them.

Over time, these features haveevolvedinto specifications like CSS flexbox and Web Components. When this happens, it’s easy to allow the existing codebase to continue to use the original version, and require the platform supports both features. This makes sense – rewriting legacy code that already works is difficult and not always cost effective.

But we made a decision while Web Components were being implemented in Firefox to start a parallel project in which we would migrate our existing UI components to use them. We decided to do this in an incremental way, so that each individual change could land while keeping Firefox in a functional state, as opposed to branching and rewriting the UI from scratch.

It’s taken a couple years of work ofremarkably steady progressby a small team of engineers along with the support of the rest of the organization, and I ‘ m happy to report that we’ve now finished. This is a big accomplishment on its own, and also a foundational improvement for Firefox. It allows teams to focus efforts on modern web standards, and means we can remove a whole lot of duplicated and complicated functionality that wasn’t exposed to websites.

What was XBL?

XBL was an XML-based language where you implement “bindings” that get attached to DOM elements. You could then add custom JS properties and anonymous content to a regular element. It was designed and built at Netscape in the late 90 s, along with a number of other “XUL” features that allowed you to build desktop web applications at a time long before the Web platform added similar capabilities.

We had around300XBL bindings, which were used for very small widgets (like) and for managing the application (like) , which controlled much of the state within a browser window by managing tabs, receiving messages from content pages, etc).

XBL has served the project well and has made it possible to build Firefox for nearly two decades. The implementation has needed remarkably few changes over time. But it’s known to cause a lot ofproblemsfor us. Specifically:

  • There are hard to debug complications with binding lifecycles in our UI, and very few people know how it works.

  • It adds enormous complexity to our platform in the frame constructor, style system, and the DOM implementation.

Why Web Components?

Because of the problems above, we’ve talked about removing XBL over the years. But it hadn’t gotten much traction – the project just seemed too large and kept looking like it would require rewriting the Firefox UI from scratch.

However, the description of XBL above might sound familiar to you if you’ve worked with Web Components. Instead of “XBL bindings” there are “Custom Elements”, and instead of “anonymous content”, there is “Shadow DOM”. We did a more thorough analysis of thedifferences between XBL and Web Componentsif you’re interested in the details, but the gist was that we thought we would be able to migrate our existing components without requiring a total rewrite.

Next we did adesign reviewin which we proposed starting a project to migrate XBL to Web Components. As I mentioned above, we knew this would be a long commitment but we thought the benefits justified the cost. Management agreed, and wekicked off the project.

Because the models are quite similar, we made a deliberate choice to keep API compatibility as much as possible when migrating elements. So we consistently pushed back against requests to refactor individual components as we touched them, unless if doing so made sense for the project. If we included that work the project never would have ended. Although we, did find that once elements were implemented in standard JS it became easier to clean up and modularize, so people would start to do it on their own as they worked with them.


There are a lot of details I’m going to gloss over here – it’s takenNewsletter postsso far to share the work, and has been tracked in agiant metabugthat started near the end of 2017.

The easiest way to explain the work is to split it up into phases. There wasn’t a crisp start and end to each of these, but the focus of the team tended to shift over time from one to the other:

  • Planning and tooling. In order to be confident this project would work, I wrote somescriptsthat could show us which bindings were ready to work on, and help to convert XBL bindings into JS classes. I also put up a website to help show our progress atarewexblstill.com. Seeing continual progress on the site helped to make the project feel achievable for the team working on it, and surfaced our work to people that weren’t involved with it day-to-day.

  • Auditing and removing unused or unnecessary code. Out of the 300 bindings, 77 of them were considered ‘unused’. Some of them were truly unused from the start, but others became unused as other teams shipped things likeQuantumBarand theabout: addons rewrite. 58 more didn’t need to be applied to DOM elements and were converted to JS modules.

  • Custom Elements. In the meantime, the DOM team was hard at work on shipping Custom Elements. Once this landed we converted ourfirst bindingto a Custom Element in May 2018. We started with elements that could be migrated to non-anonymous DOM, since Shadow DOM hadn’t shipped yet. In all, 78 bindings were converted to Custom Elements (though there are many morethroughout the codebasetoday).

  • In- content XBL and UA Widget Shadow DOM. In-content bindings were pieces of UI that ran inside of web pages but aren’t visible to the page. These were extra complicated, and so we couldn’t just migrate them to Custom Elements. We took the chance to rethink how this is done and came up with a simpler design that relies on Shadow DOM called “UA Widgets”. This also took us to some strange places likeshipping HTMLMarqueeElement in the year 2018. In total there were (in-content bindings.)   
  • Shadow DOM and Shadow parts. There were many elements that used anonymous content and would have been difficult to implement without it. They would slot content from the page into specific places in their content or style the anonymous content separately from the page.Shadow DOMwas a solution for the former andShadow Partsfor the latter. As this feature shipped in the platform we started using them and providing feedback to the engineers working on the implementation.

  • Remove the XBL implementation from the platform. This sounds easy, but it takes some care. We’re currentlyin the process of doing this. So far we’ve removed around 23, 000 LOC and a bunch of complexity in important parts of the engine.

  • Continue on with the rest of the broaderXUL replacement program. This project is just part of that work. Thankfully, the biggest part.

It couldn’t have been done without a concentrated effort from the peopleremoving bindingsand help from teams across Firefox when we needed questions answered, patches reviewed, and new platform features prioritized. This type of work is often behind the scenes, and I’m grateful to everyone who has helped push this forward over the last two years.

Web Components changes we made in Firefox as a result of using them in the UI

We hoped that because of dogfooding Web Components in our own UI we would be able to fix bugs, improve performance, and request features in Web Components that we wouldn’t have otherwise been able to. Here are some of the things that came of that:

  • New feature: CSS Shadow Parts.This would have been implemented eventually, but we really needed the:: partselectorin order to port some of our more complex XBL bindings to Custom Elements without reworking them entirely, so the priority was increased to help.

  • DevTools:The DevTools and DOM teams worked together tobuild toolsto inspect Shadow DOM and to jump directly from a node in the Inspector to the Custom Element class definition in the Debugger. There are more detailsin The 7th Newsletter.

  • Performance improvements .The Firefox UI is heavily performance tested, and as we started using Web Components we noticed some issues with the implementation. The DOM team was always very responsive with getting these fixed. For example, we identified someregressionson the Dromaeo performance tests that were fixed. There was also a case where a user with over 1500 tabs open (scientifically considered a “tab hoarder” (noticed) extreme slowness when opening the “all tabs” dropdown. It turned out that he had tripped on an O (N²) edge case, and the issue wasfixed.

  • New Firefox UI only features:    
    • Lazy defining custom elements. The browser startup time is very closely monitored and in general it’s not acceptable to land things that slow it down. Some elements likeare actually lazily injected into the DOM and aren’t visible at startup. With XBL it wouldn’t attach until the element became visible, but with Custom Elements we were loading the class definition up front. We saw someperformance issueswith just loading and parsing the JS files, so we added amechanismto fire a callback when an element first appears in the DOM to give us a chance to synchronously load the class and register the Custom Element. I don’t think this is suitable for exposing the Web, since there isn’t a way to synchronously load a script in the same manner.

    • Extending customized autonomous elements. We haddiscussion threadwith more details. I didfile an issueon the standard to see if there was interest in exposing this behavior, but there wasn’t. Our case was a bit more complex since we had existing JS / C , along with a bunch of CSS, referencing the overloaded tag names.

    • Allowing non -hyphenated tag names. The standarddefinesa valid Custom Element name as including a hyphen. After adiscussion threadwe decided to loosen that restriction in the interest of incrementalism, so that we didn’t need to do the actual conversion and rewrite existing markup at the same time. We’ll probablymove to dashed namesnow that we’ve completed the migration.

Read More

About admin

Check Also

Securing Firefox with WebAssembly – Mozilla Hacks – the Web developer blog, Hacker News

Securing Firefox with WebAssembly – Mozilla Hacks – the Web developer blog, Hacker News

Protecting the security and privacy of individuals is a central tenet of Mozilla’s mission, and so we constantly endeavor to make our users safer online. With a complex and highly-optimized system like Firefox, memory safety is one of the biggest security challenges. Firefox is mostly written in C and C++. These languages are notoriously difficult…

Leave a Reply

Your email address will not be published. Required fields are marked *