Web Components are gaining momentum in the web platform space, and frankly, it’s bittersweet for us ASP.NET Core developers. On the one hand, you can use Web Components in your current ASP.NET Core applications, as I demonstrated in a previous post, but it isn’t the best experience it could be. You’ll have flashes of unstyled content, layout shifts, JavaScript code that blocks the critical rendering path, and you’ll not get the server-side rendering (SSR) goodness developed exclusively for the JavaScript ecosystem.
In his post “THE GOOD, THE BAD, THE WEB COMPONENTS”, Zach Leatherman wrote about the ideal way to deliver web components to avoid some of the issues I described. In this blog post, we’ll see how we can use ASP.NET Core’s Tag Helpers to deliver the best experience to users when using Web Components.
The ideal Web Component delivery method
Web Components are a mix of JavaScript and HTML. Nesting your HTML within a custom element tag is best for delivering a
progressively enhanced and seamless experience. Let’s take a look at building a Counter
component. First, let’s see
what the custom element would look like on your page.
and the corresponding JavaScript would be as follows.
This allows the client to render the button
element and its CSS styles in place before the JavaScript attaches the
event listener. That’s awesome, but this technique breaks down quickly once you want to use the counter multiple times.
This is especially painful if the internal HTML is complex with multiple nodes.
Shadow Dom and Templates
With Web Components, you can avoid repeating yourself by utilizing the template
element. This template can be used in
JavaScript to clone repeated elements within an instance of a component. Let’s look at the HTML.
This is great for reducing repetition but comes at the expense of additional front-end processing. Let’s look at the updated JavaScript that now uses the ShadowDom.
You can probably tell a few things changed in the JavaScript as well. This is a bit more complex, and we lost the ability to target the elements in our components with external styles from a CSS framework like Bootstrap.
What if we could get the benefits of the first implementation with the style of the second? Well, luckily, with ASP.NET Core, we can!
ASP.NET Core TagHelpers to the rescue!
TagHelpers can do almost anything to the elements within its content, and I mean anything. Let’s look at how we might
implement a WebComponentOptimizer
tag helper in our ASP.NET Core Razor pages.
When we render the page, we will get the following HTML.
The template is processed from the HTML output, and you get some fast and snappy web components on the initial page load. That’s awesome, right?!
Well, here’s the tag helper to help you do that. Note: this is a proof of concept. Before going to a production environment, you’ll want to test and adapt this for your needs.
There are a few neat tag helper tricks here.
- Setting the
TagName
to an empty string removes the parent tag. - AngleSharp is a great way to parse the existing DOM
- You can use a formatter to optimize the final output.
If you want to try this for yourself, head to GitHub to see the whole sample.
Stretch Goals: Other Web Component Frameworks
While not shown here, I’d love someone to use the SSR support in their favorite frontend frameworks to integrate with
Razor views. This could improve the initial user experience while allowing developers to use frameworks like Angular,
Vue, and React. Since ProcessAsync
could call out to an NPM process and retrieve the starting HTML from a library.
Conclusion
Web Components are fantastic, and they have so much potential to make the user experience great for users without long pauses while the UI gets its act together. On the .NET side, ASP.NET Core could be a great option to boost the web platform with Razor’s strength. This blog post only begins to scratch the surface of what could be possible. I hope you consider this when building your following UI in ASP.NET Core as an option for delivering world-class experiences.
Thanks for reading and sharing my posts with friends and colleagues. Cheers.