Developer Decries WinForms-to-Blazor Performance Degradation
Since shipping .NET 5, Visual Studio 2019 v16.8 and more goodies recently, Microsoft has been touting speed improvements in many components -- including the red-hot Blazor project -- but some real-world developers are finding different results.
Blazor is part of the ASP.NET Core wev-dev space, and Microsoft recently reported speed gains in ASP.NET Core and Blazor with comments like:
- "ASP.NET Core in .NET 5 is the fastest .NET web framework we've ever shipped!"
- "For .NET 5, we made significant improvements to Blazor WebAssembly runtime performance with a specific focus on complex UI rendering and JSON serialization. In our performance tests, Blazor WebAssembly in .NET 5 is two to three times faster for most scenarios."
Well, WinForms developer Steve Rehling may beg to differ -- in at least one very specific use case involving CPU-intensive operations as opposed to complex UI rendering and JSON serialization.
Rehling this week penned a Stack Overflow post looking for help, titled "Need Blazor Wasm Performance Improvement on CPU Intensive Calculations." It reads:
I have a c# WinForms app that I have been converting to Blazor Wasm. It needs to perform a set cpu-intensive calculations (i.e. no IO or UI interaction) after most user inputs. The calculations entail repetitively (30-50 times) invoking a number of methods in a set of 25-35 C# class objects depending on the scenario. The same calculation code runs in the WinForms and Blazor apps.
I am seeing a ~20 fold degradation in performance under Blazor (e.g. 350ms in WinForms vs 7000ms in Blazor). Does that level of degradation make sense? Is a big part of it inherent to running within a browser? Is Blazor Wasm a big part of it somehow? I have confirmed that the degradation is spread across the calculations, not in isolated spots. Are there any ways to significantly reduce the degradation? The objects that perform the calculations could be put in a class library if that might help for some reason.
I have posted this question in the AspNetCore Discussions in GitHub, but have had no responses. I am using VS Community 2019 v16.8.2, AspNetCore 5.0, and Chrome v
A reader replied: "Yes that's expected perfomance degradation. Blazor wasm runs in interpreter mode right now (though subject to change in near future), which means only runtime itself is compiled to wasm. Then that runtime downloads and interprets IL from your dlls, and this is quite slow compared to scenario where your assemblies are compiled directly to WASM. Soon it should be possible to compile to WASM directly, and it should provide some perfomance improvement (though it will not reach the level of native .NET application anyway)."
Blazor expert Chris Sainty explained the issue further in a Stack Overflow post earlier this year titled "What’s behind the hype about Blazor?"
"Currently, Blazor WebAssembly uses interpreted mode to load and run your application," Sainty said. "In this mode, the Mono IL interpreter executes your applications .NET DLLs inside the browser. The only part of the process that is compiled to WebAssembly is the Mono runtime. In the future, the team are looking to allow developers to choose if their apps, or more likely parts of their apps, will be compiled to WebAssembly as well -- This is known as AOT or Ahead Of Time compilation. The benefit of this mode is performance, the trade-off is a larger download size."
Indeed, because of problems that plagued Microsoft's Blazor WebAssembly team, that client-side component didn't progress as quickly as Blazor Server. And that AOT functionality mentioned by Sainty will likely appear in .NET 6, scheduled to debut November 2021, addressing a .NET adoption sticking point.
Rehling wasn't encouraged by the response to his question indicating that his quoted performance degradation is to be expected. He replied: "Ugh. I was hoping that wouldn't be the answer."
Another reader offered this advice to Rehling: "Blazor Wasm does not support multi threading + frequent actions like mouse event handling are very 'heavy' for processing in a browser. Try to push action handlers in a queue and process them in background."
Note that WinForms itself experienced some problems when being transplanted from the old Windows-only .NET Framework to the open source, cross-platform .NET Core scheme (now part of .NET 5).
Microsoft's dev team late last year explained the "huge technical challenge" it faced in creating the WinForms Designer on .NET Core.
"For developers the .NET Core Windows Forms Designer (when we will release the GA version) will look and feel the same as the .NET Framework Windows Forms Designer," said Olia Gavrysh, program manager, .NET, in October 2019. "But for us it is a huge technical challenge to bring the designer to .NET Core because it requires the design surface that hosts the live .NET Core form to run outside the Visual Studio process. That means we need to re-architect the way the designer surface 'communicates' with Visual Studio."
The growing COVID-19 pandemic also caused some problems in meeting the original goals of .NET 5, such that other functionality planned to be included in the Nov. 10 debut of .NET 5 was put off to .NET 6, a long-term support (LTS) release scheduled for November 2021.
Until then, developers like Rehling are left struggling for solutions in real-world development with Blazor.
"I'm afraid I may need to completely rethink the way it works from the user's perspective if direct compiling doesn't improve performance enough," Rehling said. "I'm afraid pushing things onto a queue for background processing isn't a solution. Thanks for the thought anyway."
David Ramel is an editor and writer for Converge360.