Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fabulous 3 #1034

Open
TimLariviere opened this issue Jan 15, 2023 · 12 comments
Open

Fabulous 3 #1034

TimLariviere opened this issue Jan 15, 2023 · 12 comments
Labels
t/discussion A subject is being debated v3

Comments

@TimLariviere
Copy link
Member

Introduction

2022 saw the release of Fabulous 2, a massive upgrade over Fabulous 1.
We have revised the whole architecture to bring users a much better declarative UI DSL inspired by SwiftUI, as well as a big focus on performance and reduced memory footprint. We also opened Fabulous to allow targeting Xamarin.Forms, .NET MAUI, and Avalonia.
Overall, Fabulous 2 has been a great success.

In the continuation of this release, we think it is now time to take Fabulous even further and discuss what its successor will be.

This post will detail the goals we believe Fabulous 3 should achieve in 2023.

Active discussion is happening on our Discord server on the #v3-design-discussions channel, we encourage you to join the debate to help shape the future of Fabulous.

Goals

  1. Give Fabulous a strong independent identity.

Today, Fabulous mostly appeals to F# and .NET devs by branding itself as "F# for Xamarin.Forms", "F# for .NET MAUI", etc.
But the potential target audience is quite small:

  • Limited number of mobile .NET devs compared to the competition (Apple and Google)
  • Even more limited number of people using or willing to try F#
  • Existing .NET UI frameworks only focusing on XAML / MVVM / C#
  • Strong feelings in the .NET community about C# vs F#

All this combined gives us a hard time for the adoption of Fabulous.

Despite that, we believe Fabulous could be seen as a valid option in the declarative app dev space among Flutter, SwiftUI, Jetpack Compose, React native, and others.
No declarative UI framework really compete in the .NET space with Google and Apple frameworks, despite declarative UI being very trendy for the past few years.

To be able to achieve this, we need to give Fabulous its own independent identity.
This can be done by:

  • Providing state of the art declarative capabilities (such as widgets, layouting, animations, etc.) rather than mapping MVVM-focused controls from XF/Maui/Avalonia (see 2. for more details)
  • Advertising Fabulous on its own, no co-branding with XAML UI frameworks
  • Advertising less on F# by making the language coincidental rather than the focus (because we think functional programming is good for app dev, not because F# is cool)
  • Advertising more on the .NET ecosystem capabilities

Doing so should appeal to a broader audience that is not necessarily from the .NET community.
We would also avoid strong feelings on programming languages and years of frustration with particular frameworks.

  1. Improve the dev experience by following state of the art practices for declarative UI

From the beginning, we were simply trying to expose XAML UI frameworks capabilities in a declarative syntax.
This works for the most part, but we found many instances where porting a XAML concept into declarative UI is hard or plain impossible.

In Fabulous 3, we wish to provide a proper, full-blown, declarative dev experience by implementing our own concepts rather than trying to map whatever XAML is doing.

To avoid reinventing the wheel, we need to follow in the steps of state of the art declarative UI frameworks like Flutter and others.

This would include rolling our own implementation for:

  • Available widgets
  • Layouts
  • Animations
  • Theming
  • Environments
  1. Draw UIs

We believe Fabulous 3 should focus on drawn UIs rather than native controls.
This would reduce the number of issues related to UI inconsistencies between platforms.

We are still debating how to achieve this.

  1. Improve performance even further

Finally, we want to provide the best experience possible by improving the performance of apps built with Fabulous even further.
There is a couple ways to achieve this, but the most efficient way would be to reduce the number of layers, because each layer comes with its own bugs and performance hits.

Today, we have the following layers:

graph LR;
    Fabulous-->XAML(Xaml abstractions - XF/Maui/etc)
    XAML-->Dotnet(.NET iOS/Android bindings)
    Dotnet-->Native(Native platforms)

// cc @edgarfgp @twop @JaggerJo

@TimLariviere TimLariviere added t/discussion A subject is being debated v3 labels Jan 15, 2023
@twop
Copy link
Collaborator

twop commented Jan 15, 2023

We believe Fabulous 3 should focus on drawn UIs rather than native controls.
This would reduce the number of issues related to UI inconsistencies between platforms.

Did you do any research into drawing options? I know Avalonia comes to mind first, but I tried to explore the code, and it seems extracting rendering layer won't be easy (if possible).

@TimLariviere
Copy link
Member Author

Did you do any research into drawing options?

Not yet.
Before you mentioned in Discord owning the whole drawing stack, I was thinking of simply instantiating Avalonia controls (as opposed to "drawing with Avalonia") but still dissociate the widget tree from the Avalonia tree.
We need to do more researching on this.

@JaggerJo
Copy link

I would not go that route (custom widgets that only utilise the render/drawing layer).

Speed is important, but only to a certain point (IMHO). FuncUI is not really optimised for performance. When implementing it I often chose the simplest implementation not thinking about speed too much.

There are rarely issue regarding speed in FuncUI. If you hit a case where FuncUI is the bottleneck there are escape hatches. You can for example obtain a reference to an underlaying control in a component or you can write an Avalonia control, do custom drawing, ..

@JaggerJo
Copy link

(and I think FuncUI could be a lot faster if we'd optimise more of the internals)

@TimLariviere
Copy link
Member Author

TimLariviere commented Jan 16, 2023

Performance is a lot more important in Fabulous because we target mobile devices. Most phones on the market have low specs compared to equivalently-priced desktop devices.

Fabulous 1 was like FuncUI and only provided simple implementations, but slowness was a big issue. Navigating from one page to another could take 1-2 seconds on Android...
The Garbage Collector was pausing the app often (iOS was ok because it's using reference counting instead of GC).

In Fabulous 2, we optimized a lot for memory management by aggressively using structs and streaming the view diffing process to allocate as less as possible.

We can still see some performance bottlenecks in v2 on Android in some more advanced cases.
So, it's still something we need to focus on.

@edgarfgp
Copy link
Member

(and I think FuncUI could be a lot faster if we'd optimise more of the internals)

If you want to support mobile devices. The optimisations are a must . Fabulous v1 was pretty much unusable on Android

@JaggerJo
Copy link

Performance is a lot more important in Fabulous because we target mobile devices. Most phones on the market have low specs compared to equivalently-priced desktop devices.

Definitely see that point. Would guess that cheap android phones are the main problem.

Fabulous 1 was like FuncUI and only provided simple implementations, but slowness was a big issue. Navigating from one page to another could take 1-2 seconds on Android... The Garbage Collector was pausing the app often (iOS was ok because it's using reference counting instead of GC).

In Fabulous 2, we optimized a lot for memory management by aggressively using structs and streaming the view diffing process to allocate as less as possible.

We can still see some performance bottlenecks in v2 on Android in some more advanced cases. So, it's still something we need to focus on.

1-2 Seconds are crazy. Wonder how things can even be that slow. Guess fabulous diffs the complete view tree on every update?

@TimLariviere
Copy link
Member Author

Yes, we do diff the whole tree on every update.
That's also one of the motivation to introduce some kind of componentization where we can diff more locally.

Diffing was fairly quick even in v1, ~100ms at most, but the rendering performance were awful.
I think it was mainly due to the double VM of Android: one VM for .NET, one VM for Java - each with their own GC...

@albertwoo
Copy link

Do we have any plan for hot-reload?

@TimLariviere
Copy link
Member Author

No plans for hot reload for the moment.

Hot reload is a must-have tool, but it's also super hard to make one that would work even just for basic use cases.
If F# would have support for it, it would make it easier for us to get it in Fabulous, but F# does not support hot reload for the moment (dotnet/fsharp#11636)

The closest we had to Hot Reload was LiveUpdate in v1.
It was a proof of concept and had many issues. Turns out hot reload is more than just swapping a function for another.

An interesting podcast on the subject: https://www.mergeconflict.fm/278

@JordanMarr
Copy link

I think the idea of branding Fabulous with its own identity vs pushing the "F# for XF/MAUI/Avalonia" is brilliant. F# really needs killer frameworks to sell it -- not the other way around.

Ask any F# dev "what would you say F# is good for" and we will usually reply with "everything!" While that may be true, the rest of the world just needs one killer library to act as the gateway.

So, I really like the idea of "Declarative UI framework for .NET". If that ever became trendy, even the C# devs might jump on board (not that I really care what they do, but just saying).

@h0lg
Copy link

h0lg commented Jan 28, 2024

All this combined gives us a hard time for the adoption of Fabulous.

I would add to that list that most of the documentation seems outdated or lacking, making the dev experience for a new-comer like myself really frustrating. I learned quickly to ignore the current documentation and used the github search to piece together how to use version 2 - for lack of useful examples in the doco.

Background: I'm trying out Fabulous Avalonia ATM to give https://github.com/h0lg/SubTubular a UI after being fed up with the still bug-ridden MAUI, where I spent what felt like 80% of the development time working around known issues.

My main goal was to scope out solutions for replacing a much bigger WPF project at work. With the current dev experience (due to poor doco) though I cannot ask my team to get excited about Fabulous. Right now Fabulous seems to be a framework with great potential "for those in the know".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
t/discussion A subject is being debated v3
Projects
None yet
Development

No branches or pull requests

7 participants