The .NET Stacks #53: 🚀 This issue was compiled ahead of time
This week, we talk about Blazor WebAssembly AOT and get updates from the community.
Happy Monday, all. I wanted to thank everybody for the birthday wishes as the newsletter turned 1 last week. Also, welcome to all the new subscribers!
This week wasn't as crazy as we're recovering from Build, but as always, there's plenty to discuss. Let's get started.
- One big thing: Taking a look at Blazor WebAssembly AOT
- The little things: NuGet improvements in Visual Studio, Tye gets a VS Code extension
- Last week in the .NET world
One big thing: Taking a look at Blazor WebAssembly AOT
With Blazor, you've got two hosting models to consider, Blazor Server and Blazor WebAssembly.
With Blazor Server, your download size isn't a concern. You can leverage server capabilities with all the .NET-compatible APIs, and you can use thin-clients—you will, however, you need to consider the higher latency and scale if you have a lot of concurrent users. (Unless you have a lot of concurrent connections, it likely won't be an issue.) With Blazor WebAssembly, you can leverage client capabilities and a fully functioning app once the client downloads it. If you want to embrace Jamstack principles with a SPA calling off to serverless APIs (with attractive options like Azure Static Web Apps), Blazor WebAssembly is a nice option. The download size is larger, and apps do take significantly longer to load, though.
In my experience across the community, I do see many Blazor scenarios geared towards Blazor Server. Many times, folks are also packaging an ASP.NET Core API, and the download size and loading times of WebAssembly might be holding people back. "I want to wait until we get AOT," I've heard a lot of people say.
Last week, with .NET 6 Preview 4, Blazor ahead-of-time compilation (AOT) is finally here. With AOT, you can compile .NET code directly to WebAssembly to help boost runtime performance. Before AOT, Blazor WebAssembly apps run from a .NET IL interpreter, meaning the .NET WebAssembly code is significantly slower than a normal .NET runtime (like with Blazor Server).
I gave it a go using Steve Sanderson's Picture Fixer app featured in Build talks and the .NET 6 Preview 4 release announcement. As mentioned in the announcement, you need to do two things:
- Install the Blazor WebAssembly AOT build tools as an optional .NET SDK workload
- Add
<RunAOTCompilation>true</RunAOTCompilation>
to your project file
Then, you'll need to publish your application. On my beefy Dell XPS 15 and its 64 gigs of RAM, it took almost 15 minutes to AOT 15 assemblies and use the Emscripten toolchain to do the heavy lifting. The team notes they are working on speeding this up, but it's good to note this wait only occurs during publish time and not local development. With AOT in place, you can see dramatic changes in data-intensive tasks specifically.
As with the decision to go with Blazor Server or Blazor WebAssembly, you need to consider tradeoffs when introducing AOT with your Blazor projects. As AOT-compiled projects are typically double the size, you need to consider the value of trading off load time performance for runtime performance. You can pick and choose when you use AOT, of course, so typical use cases would take a hybrid approach and leveraging AOT specifically for data-intensive tasks.
When Steve Sanderson talked to us a while back, he said:
If we can get Blazor WebAssembly to be faster than JS in typical cases (via AoT compilation, which is very achievable) and somehow simultaneously reduce download sizes to the point of irrelevance, then it would be very much in the interests of even strongly JS-centric teams to reconsider and look at all the other benefits of C#/.NET too.
AOT is a big step in that direction. The size of the .NET runtime will never compare to small JS frameworks, but getting close to download size and performance will be a giant step towards providing a modern, fast SWA solution for folks open to the .NET ecosystem.
NuGet improvements in Visual Studio, Tye gets a VS Code extension
Last week, Christopher Gill announced that Visual Studio is introducing NuGet Package Suggestions in Visual Studio 16.10. With IntelliCode Package Suggestions, NuGet uses your project's metadata—like what packages you have installed and your project type—to suggest packages you might need. Package suggestions are shown in the NuGet Package Manager UI before you enter a search query.
As for the fine print, it currently only works on the project level and does not suggest packages outside of nuget.org. Also, it won't support deprecated packages or ones that are transitively installed.
Also from last week, Microsoft rolled out a Visual Studio Code extension for Tye. If you aren't familiar Project Tye is an open-source project that helps developers work with microservices and distributed applications.
We're seeing a lot of nice updates for Tye, and I wonder when it'll get out of the "it's experimental, things might break" phase. For example, the official repo on GitHub still states: "Project Tye is an open source experiment at the moment. We are using this time to try radical ideas to improve microservices developer productivity and see what works...For the duration of the experiment, consider every part of the tye experience to be volatile." It has a lot of nice use cases with Dapr, for example, and I'd love to see when Microsoft is going to put a ring on it.
🌎 Last week in the .NET world
🔥 The Top 3
- David Pine builds a video chat app with ASP.NET Core 5.0, Angular 11, and Twilio Programmable Video.
- Christopher Gill introduces IntelliCode package suggestions for NuGet in Visual Studio.
- Mark Downie interprets async code in CPU traces.
📢 Announcements
- Jon Galloway announces Visual Studio 2019 for Mac version 8.10.
- Pratik Sanglikar announces the Visual Studio Code extension for Tye.
- Dapr 1.2 is now available.
- Josh Love introduces the Azure Functions extension libraries for the Azure SDK.
- In JetBrains news, Khalid Abuhakmeh introduces real-time inspections in dotMemory Allocation Analysis, Alexander Kurakin announces an EAP for Rider 2021.2 and ReSharper 2021.2, and Cake for Rider 1.0 is released.
📅 Community and events
- Aaron Stannard chimes in on the IdentityServer drama.
- For community standups: Xamarin recaps Build 2021, and Entity Framework introduces EF Core compiled models.
- Stack Overflow was acquired for $1.8 billion.
🌎 Web development
- Hassan Habib builds contextual experiences with Blazor.
- Cody Merritt Anhorn builds a template using Blazor and Contentful CMS.
- David Grace builds a Connect 4 game with Blazor.
- Damien Bowden verifies vaccination data with ASP.NET Core and Mattr.
- Gopi Govindasamy dynamically renders a component in a Blazor app.
- Jon Hilton walks through choosing a Blazor component library.
- Marinko Spasojevic writes about asynchronous programming with async and await in ASP.NET Core.
🥅 The .NET platform
- Kristoffer Strube writes about new LINQ extensions in .NET 6.
- Richard Lander posts a discussion about the .NET type system and about .NET interop.
- Andrew Lock benchmarks various reflection methods for calling a constructor in .NET.
- Christos Matskas writes about secure and minimal APIs using .NET 6, C# 10, and Azure Active Directory.
- Khalid Abuhakmeh works with the PriorityQueue in .NET 6.
⛅ The cloud
- Maarten Balliauw uses custom bindings with the Azure Functions .NET isolated worker.
- Davide Bellone introduces using Azure Service Bus with C#.
- Théo Rémy works on stateful serverless workflows with Azure Durable Functions.
- Thomas Maurer runs cloud-native apps on Azure PaaS anywhere.
🔧 Tools
- Abhijit Jana switches between Git branches and repos in Visual Studio and removes unused references in Visual Studio.
- Nicholas Blumhardt customizes Serilog text output.
- Russell Smith gets started with the Windows Package Manager, and Matthew MacDonald offers his honest appraisal.
📱 Xamarin
- James Montemagno writes about building beautiful apps with Xamarin.
- Luis Matos recaps .NET MAUI Preview 4.
- Sam Basu provides his weekly MAUI update.
🏗 Design, testing, and best practices
- Jimmy Bogard starts a series on domain-driven refactoring.
- Vladimir Khorikov writes about nulls in value objects.
- Derek Comartin talks about the Competing Consumers Pattern.
🎤 Podcasts
- The Overflow talks about observability and OpenTelemetry.
- The 6-Figure Developer podcast talks to Cecil Phillip about Dapr.
- The Azure DevOps Podcast recaps Build 2021, and so does Merge Conflict.
- The No Dogma Podcast talks to Martin Beeby about using .NET on AWS.
- The .NET Core Podcast talks to Tanya Janka about application security.
🎥 Videos
- The ASP.NET Monsters deploys with GitHub Actions.
- On .NET talks about C# string interpolation and async streams.
- Technology and Friends talks to Jeff Wilcox about open source at Microsoft.
- Data Exposed sets up Azure Monitor for SQL Insights.