microsoft / microsoft-ui-xaml

Windows UI Library: the latest Windows 10 native controls and Fluent styles for your applications
MIT License
6.36k stars 678 forks source link

Proposal: XAML support should become a Visual Studio extension #7162

Open SetTrend opened 2 years ago

SetTrend commented 2 years ago

I propose to outsource XAML into a Visual Studio extension and drop it from runtime, design-time and build-time.


With the proposed – optional – Visual Studio extension, designers and programmers may choose whether they want to utilize XAML (by installing the proposed VS extension) or deal with the runtime directly and fast.

  1. The extension is supposed to transpile .xaml files into *.designer.* partial class files at design time and to keep both in sync (by watching the corresponding files/folders).

  2. Designers' experience won't change. They still will be using .xaml files. Yet, the suggested Visual Studio extension will immediately transpile these to *.designer.* partial class files.

Rationale

(Please pardon me for the following long essay. I'll try to lighten it up with some animations depicting the corresponding description for better reading.)

Different designers


By outsourcing XAML to a Visual Studio extension and at the same time removing XAML support from current XAML project types (e.g. WPF, WF, UWP, Xamarin.Forms, MAUI, Uno Platform) themselves, this would greatly reduce the current overhead for dealing with XAML:

  1. The Visual Studio designer could JIT compile its partial *.designer.* files and run them immediately to display its surface ‒ instead of being required to parse XAML, find the corresponding objects via Reflection and trying to instantiate each of the objects manually.

  2. The compiler could just compile the *.designer.* partial classes along with the user defined partial classes. No additional pre-build step would be required to transpile XAML to native .NET language code by parsing the XML, finding the corresponding objects via Reflection and derive code for each of the objects manually.

  3. The Windows Runtime wouldn't be required to read and parse BAML/XBF files at runtime and find the corresponding objects in memory to complete the object tree.

Remove XAML support


Benefits are ...

The proposed extension is supposed to provide the following functionality ...

  1. The extension provides a file watcher that's syncing XAML files from *.designer.* files and vice versa.

1_ 2_ 3_

Summary

I propose to create a Visual Studio extension that transpiles .xaml files to *.designer.* files.

This will enable all current XAML project types to have any XAML support removed/stripped while designers will still be able to utilize XAML.

The Visual Studio debugger's Compile and Continue feature will still allow to edit both,.xaml files and *.designer.* files, during debugging.

The .NET runtime may still provide methods for parsing XAML at runtime, but these will not intrinsically be used but only by programs that explicitly call them.


/ref: #4127 @VagueGit : done

sylveon commented 2 years ago

Much of the problems I've brought up in the original issue have not been addressed by this update. Namely:

So, it does not actually result in faster developments, builds or runtime. It actually worsens all 3 in C++.

Designer files also should preferably not be checked in to source control. The source of truth, in this case the developer-edited XAML files, should be checked in. Checking in the designer files and regenerating XAML from them would lead to losing important information like comments. It makes reviewing UI changes harder too - if the Winforms designer is anything to go by, a small change (like moving a control by a few pixels) can entirely reorganize the designer file, making code reviews practically impossible, especially on complex forms.

Neither the XAML designer or the XAML compiler actually use reflection - in case of the XAML designer the code is actually loaded and ran within the IDE - your code runs in the designer itself (and there are APIs to detect this). As for compilation, I'm pretty sure the XAML compiler relies on WinMD metadata, generated by the C# compiler (or IDL files in C++). These two facts are evidenced by the fact you need to compile the project at least once for the designer features to even show up, and that in C++ you need to add anything you want to x:Bind to in an IDL file.

Additionally, some XAML concepts like DataTemplates and retemplating cannot be represented in code currently, only XAML.

Another issue is that this increases coupling of WinUI with VS - it would leave users who desire to use XAML from other IDEs without the possibility of doing so, or force Microsoft/the community to implement extensions for many IDEs out there, instead of being able to rely on the build system to handle their XAML files for them. The XAML compiler finally became a standalone exe instead of a MSBuild task in WASDK 1.2 - let's not revert that.

SetTrend commented 2 years ago
* The fact XAML supports other languages like C++, which are incredibly more complex to parse, leading to a poor designer experience. (for ex, much longer time to initially render and update the designer view due to requiring code compilation)

Can you give an example of much more complex C++ Managed Extensions would compared to .NET CLR to render for a designer?

What do you believe the current implementation does when you hit Build Project?

* The fact the C++/WinRT projection is quite heavy, and that piles of autogenerated code creating and laying out controls will inevitably make compile times longer than turning XAML files into XBF.

On the contrary: complile times will shorten – because there won't be anything left to compile.

Please make sure to grasp the proposal fully.

Additionally, some XAML concepts like DataTemplates and retemplating cannot be represented in code currently, only XAML.

That ain't true. There isn't something like "XAML" as you perceive it. All XAML is getting converted into C++. There is always a code representation of any XAML you write.

Are you sure you understood the XAML concept completely?

Another issue is that this increases coupling of WinUI with VS - it would leave users who desire to use XAML from other IDEs without the possibility of doing so, or force Microsoft/the community to implement extensions for many IDEs out there, instead of being able to rely on the build system to handle their XAML files for them. The XAML compiler finally became a standalone exe instead of a MSBuild task in WASDK 1.2 - let's not revert that.

That ain't true, either. These already exist. How do you believe you'll get to see a visual representation in your IDE?

sylveon commented 2 years ago

Can you give an example of much more complex C++ Managed Extensions would compared to .NET CLR to render for a designer?

The version of C++ that UWP and WinUI XAML supports is not managed, and does not run on the .NET CLR. It is native C++. Compiling C++/WinRT code is much heavier than the equivalent C#, due to C++/WinRT being a library that's very liberal with its use of templates, a C++ feature that is already inherently expensive to parse/compile. The C++ compiler has to parse that code everytime too, while the C# compiler just parses metadata.

Examples where brought up in the original thread too, for example the fact that C++ has at least 20 different ways to initialize a variable. You'd practically need to implement a full C++ parser/AST to be able to support C++. At which point, one could also take a look at the C++ parser of compiler projects like Clang and GCC. It is massive and very complicated, and to this day, still bugs out ever so often.

On my i5-5200U laptop (now admittedly this is a bit old, but it's still pretty long even on my Ryzen desktop), simply writing the following (which is required to use XAML):

#include <winrt/Windows.UI.Xaml.Controls.h>

Makes the build take an additional 2-3 minutes, even if nothing from that namespace is actually used. The more controls/properties you use, the longer it will take to compile.

What do you believe the current implementation does when you hit Build Project?

Builds the code, of course. But a designer should not take several minutes building code in the background just to show or update a preview. For bigger projects, this could be as high as half an hour of building code instead of a several minutes.

On the contrary: complile times will shorten – because there won't be anything left to compile.

You are suggesting to generate a significant amount of code that will need to be compiled, instead of a small binary file and a small amount of code. I don't see how that would make compile times shorter, especially considering the slow compile time of C++.

That ain't true. There isn't something like "XAML" as you perceive it. All XAML is getting converted into C++. There is always a code representation of any XAML you write.

While the framework does end up with an internal representation of the DataTemplate, currently it is not possible for users to create a DataTemplate purely from code, without XAML. The class that allowed this in WPF (FrameworkElementFactory) does not exist in UWP. The only way is to use XamlReader to parse XAML at runtime, which is much slower than loading a DataTemplate that was compiled to a XBF file.

Are you sure you understood the XAML concept completely?

This kind of remark is disrespectful and offtopic, please avoid them.

That ain't true, either. These already exist. How do you believe you'll get to see a visual representation in your IDE?

Sure, a few GUI designers for XAML exist in other IDEs, but their only responsibility is generating a preview from the XAML. They do not parse code, or generate big amounts of code. The task of compiling XAML and generating XBF is left to the build system, because XAML support is part of the build system.

If it was moved to a VS extension, now every extension also has to get in the business of parsing code for a designer, and generating code. We would ultimately get divergence between addons (code generated from IDE A may not be understood correctly by IDE B's designer) and it would become even harder to add designer support to other IDEs compared to today. Also, if you're writing XAML without a designer (in tools like VSCode or vim, for example), you would need an addon, instead of being able to just build the project and get the required code/XBF generated.