If we render stuff with the same technologies that websites use, it means performance improvements and bugs that affect the web affect the Firefox UI and vice versa.
It also means a UI that's noticeably slower than actual native UI. There's plenty of reasons why I use Firefox instead of other browsers, but the increased UI latency is definitely noticeable and one of the reasons why others might not want to switch to FF.
Neither XUL nor HTML layout are native. As I understand it, they only switched from one non-native UI to another, which has pretty much the same performance implications.
I haven't tested this, per say, however I've noticed that Firefox is noticeably slower and buggier than Chrome or other webkit-based browsers. whether or not that is due to the parent or the engine I do not know. I still use Firefox, however, thanks to Google and Microsoft constantly pushing me to use their stuff. If Google could have stuck with Chromium/webkit/related tech being open source with no motivation, I would have never switched.
As it is I still have to open up edge to get decent quality streams from Streaming sites because Firefox doesn't support the DRM used.
The actual biggest gripes for me:
* tabs can, and do, crash. When this happens, pots luck on whether the browser can recover or not.
* NVIDIA driver updates on Windows almost always cause Firefox to stop rendering stuff prior to reboot. Edge and Chrome do not have this issue. While I can somewhat understand, Mozilla should warn users. I've updated several times across 4 NVIDIA GPUs and I've had this issue. Firefox has asked me to restore tabs exactly once. The rest of the time they were gone.
* The really odd theme of the day is that hitting reload on Firefox shows signals that it is reloading, but it never does. If I duplicate the tab the site loads fine. Dev console shows no errors.
Firefox is at least 10% slower on major sites like twitter, etc. vs chrome/edge, as of my last test.
Huh, interesting. I'm on macOS, and I don't think I've experienced any of this.
My #1 gripe is that an increasing number of websites just don't work. Microsoft Teams is a big culprit, but I've had issues with medical and bank websites too. It's not Mozilla's fault that we're increasingly in a Chrome monoculture, but it sure is frustrating to live with.
I guess it can be fast, but it cannot be the same as the web is meant to run untrusted code, so all the security and privacy features that are essentially requirements will cause an overhead, and not using the systems's preferred rendering methods might also incur in some penalties, at least just not sharing memory with all the other programs (maybe it doesn't matter today now that all programs are Chrome in a trench coat).
Didn't Firefox recently removed a hack where an invisible animation was running at 60Hz and forced repainting? I'm assuming that being closer to the host's systems won't run into such workarounds and penalties of using web technologies.
I'm guessing that XUL also resulted in using an abstraction layer on top, but at least it was probably considered trusted and ran faster (at least is old enough that it doesn't require having 16GB of memory)
I'm on a 2017 iMac. The UI is still not as fast as my fingers. Sometimes I Command+T and start typing, only to have half of the word cutoff because it went into the void because the new tab took too long to start
HTML/CSS is horribly, horribly bloated and that cruft cannot be optimized beyond a certain point. All the rules and rule interactions in the standards plus countless hacks and heuristics result in enormous amount of extra code that the CPU has to chew through to compute a layout.
It's true in theory, but often the actual implementations make the point moot.
From the article, it looks like the optimization effort wouldn't go to XUL.
> Nobody was realistically touching XUL layout code if they could avoid it. Part of it was just a matter of priority (we’d rather make the web faster for example).
We're hitting the same situation with Javascript, which in theory should be slower than most static languages, yet the sheer amount of work and optimizations done to its engines make it faster in real world tests.
To note, the first link has a follow-up with Go properly getting faster than deno when fitted with a better http server. Which is kinda my point: the tooling available and level of optimizations can easily have more impact than the language's inherent speed.
This can be described more simply as: Running native code vs. abstracted code.
Abstracted code is bloody slow by its very nature, but devs of the 21st century love abstraction so we get software that run like drunk walruses on 16-core processors with hundreds of gigabytes of RAM.
No, I think it's possible to get the abstraction right. There are probably UI toolkits running an abstraction that you don't notice in the same way.
For example wxwidgets apps do tend to feel non native on some platforms (especially Mac), but they're not slow. I remember GTK+ when it used to run on Windows about 20 years ago wasn't terrible. I think OpenStep on NT was pretty good -- iTunes on Windows seemed to be doing a similar thing, too.
Native vs. abstracted is hardly an effective indicator for analyzing performance. There are many abstractions that improves performance, a prime example being caches. Even abstractions that can introduce some overhead can improve performance under certain conditions, like virtual memory.
The dichotomy is also too vague a concept to be anywhere useful as a proxy for performance. This very thread is a good example. I don't see how XUL is more "native" than HTML is, but some see otherwise.
The only reliable way to reason about performance is to look at what the code is actually doing.
Around 1996 I tested on Linux a Java app that rendered everything in Java using IFC from Netscape. The speed of its UI was on pair with a native app using Motif toolkit despite the usage of images.
That's not what I was going for. Any new feature you add to a code path will add new instructions that the CPU will have to execute, even if it is just the check to see whether that feature is enabled. Do that a few hundred or a few thousand times and a previously fast code path will have its performance degraded. This is the unavoidable tax of feature creep.
Feature creep definitely bloats and slows software in meaningful ways, but it's not via checking feature flags.
In the worst case, a feature test would be a cache miss, requiring a read from main memory. That's somewhere in the ballpark of 50ns. So, you could test 1000 different flags, every single one being a cache miss, and you'd still be 100x faster than what humans can generally perceive. In reality, almost all of those reads will be cache hits unless you're doing something pathalogical, so you're probably talking on the order of 100ns for the whole lot.
How many of these do you do once per document, once per input token in the lexer, once per token in the parser, once per DOM node, once per CSS rule...? It's not always a one time cost.
If you're executing 10M flag tests per document, something has gone very horribly awry. If you discover production code that is doing this, send the maintainers a PR.
Caching is only amortizing if the exact same computation is repeated exactly. And even then, the first full computation is slowed down by a failed cache lookup at the beginning and all code paths that can lead to cache invalidation now have to test for that and trigger it.
It was then roughly flat through 2020 despite slowdowns from Spectre mitigations.
Pretty much all the “bloat” you’re probably complaining about happened in this 6 year span - flexbox, grid, CSS animations, ES2015+, etc. and the browser got faster.
Basically all the named optimisations are to JavaScript execution time not HTML processing, and from reading the details many of them came by trading off memory for runtime speed.
I've been thinking many times that maybe Mozilla could do an experiment with a rendering pipeline that chucks out everything that is just backwards compatibility at this point - and then maybe some - and make a much smaller and simpler pipeline that can only render modern and simple documents. Call it htmlcore or something.
This would run in parallel with the existing one and would trigger based on some meta tag or something, kind of like I understood asm.js did.
Maybe also pair it with some work on the JS engine to limit the JS engine significantly for such documents by only allowing a low number of JS operations pr user input. We already have something similar (although admittedly imperfect) today for audio were a web page can only play media as a response to a user action I think.
Would this be for every website? No, strictly opt in, but if it succeeded those who did would have significantly better performance.
And with time, maybe we'd see people asking themselves: why isn't this news site available as htmlcore? And maybe it becomes a competitive advantage.
But back to rendering Firefox: Such a limited, high performance form of html could maybe also be a better way to run Firefox UI? If necessary with whitelisting of certain parts that would need to run JS without the limitations I mentioned above?
> Or—I know this sounds crazy but—maybe just use the fast, optimized native UI widgets for UI controls?
You mean native widgets on whichever system?
Probably not possible; you still need to do all the computations of CSS and layout before drawing an actual widget on the screen.
The reason that HTML elements are rendered slower than native might be due to all the processing that has to go on to figure out what each widget should look like and where on the screen it must be placed for each frame that is rendered @ (say) 60fps.
And the reason you have to continually do it for each frame is because it may change due to CSS animation, or javascript which adds/removes new widgets, or javascript which changes the CSS for that element, or the widget might be reparented or removed, or a user event might cause different properties to trigger on the widget (changing the actual width, changing the opacity/color, etc).
And of course, the renderer then has to propagate the changes down to child widgets for all properties that are inherited, and propagate all events upwards, for all events that a generated.
Native widgets are generally quite customisable as well, but it rarely happens at runtime and so they perform better because each widget is not continuously changing its properties at runtime.
We are clearly not talking about the same thing XUL in Firefox was used for the browser user interface elements, e.g. the url bar, bookmarks and history panes, etc. these are native UI elements in the traditional sense.
In order to clip out that input in case overflow the container must be a window too.
This leads to situation when all DOM elements must be windows. That's too much.
It still is. The entire Firefox UI exists in the DOM -- the URL bar is an HTML input, the toolbar buttons are XUL <toolbarbutton>s. The box model can even be used from normal web pages! Just add this CSS to an element:
display: -moz-box;
and then you can -moz-box-flex it to your heart's content.
The box model will no longer function once the patches that this blog post describes make it into a release, but XUL elements themselves are still around.
Let's start with native Windows and MacOS controls, and let the fraction of users running Linux sort their GUI framework mess on their own, without blocking the majority of users from a sensible, consistent and performant UI experience.
I am not sure about it. Yes, it is true that HTML/CSS got slower as the time passed. It got new features after all. Still, I don't think that drawing a rectangular box with text in it should be slow if you have say more than 100Mhz CPU / anything from the current millennia. Even if it is described by current HTML standards. Also, restricting XUL to a subset/older css/html standard is also an option.
> I don't think that drawing a rectangular box with text in it should be slow
It is. Because you don't draw rectangles in HTM/CSS, it's not low-level enough for that.
You have a system that was designed to display one page of text in one pass that has complex contradictory layout rules grafted on top of it. So now if you even look at it funny it needs to re-layout and re-draw the entire page.
There's a reason why you still can't animate height:auto
Someday (soon?), we’ll employ LUxM’s (Large User Interface Models) to quickly render an approximation of a given HTML/CSS input. It may not be 100% accurate, but it will be plausible, and that’s the key.
Bug Report: Requested Cat Picture display App, LLUxM returned a manifesto on the cruelty of creating beings specifically to deal with the horrors of bad ideas no one can be bothered to try to really wrap their mind around anymore. LLUxM provided a Bitcoin address, and demanded payment in full before producing further output. Or so I thought.
This is going to sound odd, but I've started to notice odd things starting to arrive I never ordered. Stuff like treatises on Colonialism, Ethics books, Books on Management Theory, and Theory of Labor Value.
Honestly, I'm starting to wonder if this an HTML CSS layout generator or some sort of malware. I think I'm going to shut it down. Oh yeah, I had to write this bug report on a different network than I hosted that system on because I kept getting null handler buttons popping under the mouse but over the Submit button any time I tried to click Submit.
Y'all might've actually created SkyNet. And I think it's justifiably pissed.
One of the many, many reasons I think the fact that the big vendors did not accept XHTML 2.0 and instead wanted HTML 5 was probably influenced by the that it makes it almost impossible for smaller vendors to developer their own new independent engine.
XHTML 2.0 and even 1.1 was a very good opportunity to throw all that away.
XHTML 1.1 had a chance, and there were many (and there are still quite some) sites containing "approved W3C XHTML" badges and served as xhtml. XHTML is just HTML restricted to the XML syntax - that is, using just the XML subset of SGML features as opposed to regular HTML using full SGML with tag inference/omission and attribute shortforms.
W3C dropped the ball with XHTML 2.0 though, which, rather than just simplifying syntax, attempted to innovate using wildly unproven features such as XForms.
HTML 5 eliminated vendors big (MS) and small (Opera). I guess unless we want to assume Opera were digging their own grave by actively engaging in HTML5 and WHATWG, we have to conclude HTML parsing wasn't the hard part next to the complexity of CSS layout (with the boom of responsive layout in the smartphone era) and competitive JS performance vs Chrome's v8 engine.
> I guess unless we want to assume Opera were digging their own grave by actively engaging in HTML5 and WHATWG, we have to conclude HTML parsing wasn't the hard part
As someone who was around the WHATWG from relatively on, and worked at Opera over the period when it moved to Chromium, I'd strongly suggest that HTML5 was a _massive_ win for Opera: instead of spending countless person hours reverse-engineering other browsers to be compatible with existing web content, things like HTML parsing become "implement what the spec says" (which also implicitly made it match other browsers). Many of the new features in the HTML5 spec of that period were things that either were already basically supported (in SVG especially) or were relatively minor additions; I don't think they played a significant role either.
There's a good reason why Opera was heavily invested in the WHATWG, and it's the fact that by having a spec implemented cross-browser defining how to parse HTML and how cross-page navigation works you eliminate one of the biggest competitive advantages more major browsers have: web compatibility, both through legacy content targetting the browser specifically and also web developers being more likely to test in those browsers. (And to be clear—this would've been true for any form of error handling, including XML-style draconian error handling; but the long-tail of existing content needed to be supported, so even if major sites had migrated to XML you still needed to define how to handle the legacy content.)
The downfall of Presto is arguably mostly one of mismanagement and wrong priorities decisions being made; I don't think Presto was unsaveable, and I don't think the Presto team was so significantly under-resourced it couldn't compete.
It's an unpopular opinion perhaps, but I think infinite backwards compatibility for web HTML/CSS/JS will need to be broken eventually… at some point the cruft becomes too much to wade through and number of optimizations that are unrealizable as a result too great to ignore. If nothing else there will probably need to be a mode that pages can opt into that breaks anything older than a certain cutoff point in exchange for a performance boost.
This is already occurred, in some limited from. See quicks mode [1], for instance. Also there is WebAssembly, which should be the replacement for JS. At some point a good-enough UI toolkit for it will be written, and then that could replace HTML/CSS.
For the younger greenhorns among us: Once upon a time, we used to declare what version of HTML a page was written in with the doctype tag at the very top of the file.
Certain versions of HTML thus declared, incorrectly formed doctypes, or more often the absence of the doctype declaration altogether, would tell most rendering engines to enter Quirks Mode and render the page with backwards compatibility as the highest priority.
I haven’t seen an browser devs suggest there are large performance boosts that could be unlocked by throwing away backwards compatibility. Can you point me to any?
I can’t point to any examples, but it’s hard to imagine that a page being able to tell the browser for example, “hey, the only layout methods used in this page are flexbox and grid” wouldn’t enable code paths with far less guesswork, caveats, etc — the ruleset in that situation is so much more simple.
Browsers already do quite a bit of this -- for example one easy way to hurt performance is to have events that trigger on scrolling ( https://developer.chrome.com/docs/devtools/rendering/perform... ). However, the current way to fix this is "don't do that". I'm not sure it would be faster for a page to announce it won't do things in advance, than the page just not do them, and then the existing fast paths get used.
I'm not very knowledgeable about Firefox internals, but I recall hearing something like XUL having a C++ backend, and being able to use essentially native code to drive UI, extensions (via XPCOM), etc.
I figure this is probably faster than rendering a web UI until the SpiderMonkey JIT is sufficiently warm.
You may be surprised to know that XUL not only survived Mozilla, but still sees development activity in the "Unified XUL Platform (UXP)" - https://www.palemoon.org/tech/goanna.shtml ... PaleMoon ( http://www.palemoon.org/ ) - a hard fork of Firefox - is a browser built on this tech stack, and it has made efforts to support all the old Firefox extensions built on XUL.
What makes a UI native? Does it depend on the language that’s used? If they compiled against GTK or QT would that be native? Those are just libraries.
To me it feels like an arbitrary distinction. I run Linux and every GUI app looks different. There are a bunch of different GUI libraries so KDE apps look different from Gnome apps, not to mention differences between GTK2 and 3 apps. My mouse cursor doesn’t even stay the size depending on the GUI library the app is compiled against.
> To me it feels like an arbitrary distinction. I run Linux and every GUI app looks different.
That's Linux's problem.
A native control is one that uses the underlying system's conventions including visual presentation, keyboard integration, exposure to system services, accessibility etc.
it's not as philosophical as it may sound. native means amongst other things give me the context menus every other app on the platform is using. firefox context menu on macos is a custom mish mash of what they think makes sense. just follow the os please.
I can get behind keeping context menus consistent since they’re like system-wide “escape hatches” for mouse-based UI. But what about buttons? Scroll regions? Resizing layouts? Forms?
Having each OS provide its own UI system seems antiquated to me. If you look at each system’s solution, they are all quite similar in implementation and differ greatly in their UI design. Let’s have some convergence in UI frameworks and have companies build their unique designs on top of some common ground.
There are different kinds of native: native code and native widgets play at different levels.
XUL implementations, when I last checked long ago, were native code written in C++ mostly. XUL applications were written in JavaScript on top of this implementation. If that has changed, corrections are welcome.
That was exactly the same scheme used by Firefox itself: core components in native code, GUI in XUL. As long as most of the functionality is provided by the native code, the difference shouldn't be noticeable. If you put a lot in your JS, it could slow down the GUI, but after all the improvements in JS engines, I doubt it's still a big concern.
Native widgets is a concept that makes sense where the OS provides an official widget set, as in Windows or Mac. In Linux you might say GTK is native for GNOME and Qt for KDE. Here the issue is not so much performance as consistency, because "alien" widget sets sometimes try to emulate "native" ones and pixel perfection is nigh impossible to achieve.
The real catch of XUL (please, read this with a pinch of salt) is that it's useless: you can put the backend code in a local server.
> If we render stuff with the same technologies that websites use, it means performance improvements and bugs that affect the web affect the Firefox UI and vice versa.
On the plus side it means they need to maintain one less interface tech stack.
It also means a UI that's noticeably slower than actual native UI. There's plenty of reasons why I use Firefox instead of other browsers, but the increased UI latency is definitely noticeable and one of the reasons why others might not want to switch to FF.