https://nolanlawson.com/2024/09/28/web-components-are-okay/ Read the Tea Leaves Software and other dark arts, by Nolan Lawson [Search this Blog ] Search * Home * Apps * Code * Talks * About << Improving rendering performance with CSS content-visibility 28 Sep Web components are okay Posted September 28, 2024 by Nolan Lawson in performance, Web, web components. Leave a Comment Every so often, the web development community gets into a tizzy about something, usually web components. I find these fights tiresome, but I also see them as a good opportunity to reach across "the great divide" and try to find common ground rather than another opportunity to dunk on each other. Ryan Carniato started the latest round with "Web Components Are Not the Future". Cory LaViska followed up with "Web Components Are Not the Future -- They're the Present". I'm not here to escalate, though - this is a peace mission. I've been an avid follower of Ryan Carniato's work for years. This post and the steady climb of LWC on the js-framework-benchmark demonstrate that I've been paying attention to what he has to say, especially about performance and framework design. The guy has single-handedly done more to move the web framework ecosystem forward in the past 5 years than anyone else I can think of. That said, I also heavily work with web components, both on the framework side and as a component author. I've participated in the Web Components Community Group and Accessibility Object Model group, and I've written extensively on shadow DOM, custom elements, and web component accessibility in this blog. So obviously I'm going to be interested when I see a post from Ryan Carniato on web components. And it's a thought-provoking post! But I also think he misses the mark on a few things. So let's dive in: Performance [T]he fundamental problem with Web Components is that they are built on Custom Elements. [...] [E]very interface needs to go through the DOM. And of course this has a performance overhead. This is completely true. If your goal is to build the absolute fastest framework you can, then you want to minimize DOM nodes wherever possible. This means that web components are off the table. I fully believe that Ryan knows how to build the fastest possible framework. Again, the results for Solid on the js-framework-benchmark are a testament to this. That said - and I might alienate some of my friends in the web performance community by saying this - performance isn't everything. There are other tradeoffs in software development, such as maintainability, security, usability, and accessibility. Sometimes these things come into conflict. To make a silly example: I could make DOM rendering slightly faster by never rendering any aria-* attributes. But of course sometimes you have to render aria-* attributes to make your interface accessible, and nobody would argue that a couple milliseconds are worth excluding screen reader users. To make an even sillier example: you can improve performance by using for loops instead of .forEach(). Or using var instead of const/let. Typically, though, these kinds of micro-optimizations are just not worth it. When I see this kind of stuff, I'm reminded of speedrunners trying to shave milliseconds off a 5-minute run of Super Mario Bros using precise inputs and obscure glitches. If that's your goal, then by all means: backwards long jump across the entire stage instead of just having Mario run forward. I'll continue to be impressed by what you're doing, but it's just not for me. Minimizing the use of DOM nodes is a classic optimization - this is the main idea behind virtualization. That said, sometimes you can get away with simpler approaches, even if it's not the absolute fastest option. I'd put "components as elements" in the same bucket - yes it's sub-optimal, but optimal is not always the goal. Similarly, I've long argued that it's fine for custom elements to use different frameworks. Sometimes you just need to gradually migrate from Framework A to Framework B. Or you have to compose some micro-frontends together. Nobody would argue that this is the fastest possible interface, but fine - sometimes tradeoffs have to be made. Having worked for a long time in the web performance space, I find that the lowest-hanging fruit for performance is usually something dumb like layout thrashing, network waterfalls, unnecessary re-renders, etc. Framework authors like myself love to play performance golf with things like the js-framework-benchmark, and it's a great flex, but it just doesn't usually matter in the real world. That said, if it does matter to you - if you're building for resource-constrained environments where every millisecond counts: great! Ditch web components! I will geek out and cheer for every speedrunning record you break. The cost of standards More code to ship and more code to execute to check these edge cases. It's a hidden tax that impacts everyone. Here's where I completely get off the train from Ryan's argument. As a framework author, I just don't find that it's that much effort to support web components. Detecting props versus attributes is a simple prop in element check. Outputting web components is indeed painful, but hey - nobody said you have to do it. Vue 2 got by with a standalone web component wrapper library, and Remount exists without any input from the React team. As a framework author, if you want to freeze your thinking in 2011 and code as if nothing new was added to the web platform since then, you absolutely can! And you can still write a great framework! This is the beauty of the web. jQuery v1 is still chugging away on plenty of websites, and in fact it gets faster and faster with every new browser release, since browser perf teams are often targeting whatever patterns web developers used ~5 year ago in an endless cat-and-mouse game. But assuming you don't want to freeze your brain in amber, then yes: you do need to account for new stuff added to the web platform. But this is also true of things like Symbols, Proxys, Promises, etc. I just see it as part of the job, and I'm not particularly bothered, since I know that whatever I write will still work in 10 years, thanks to the web's backwards compatibility guarantees. Furthermore, I get the impression that a wide swath of the web development community does not care about web components, does not want to support them, and you probably couldn't convince them to. And that's okay! The web is a big tent, and you can build entire UIs based on web components, or with a sprinkling of HTML web components, or with none at all. If you want to declare your framework a "no web components" zone, then you can do that and still get plenty of avid fans. That said, Ryan is right that, by blessing something as "the standard," it inherently becomes a mental default that needs to be grappled with. Component authors must decide whether their s should work like native s. That's true, but again, you could say this about a lot of new browser APIs. You have to decide whether IntersectionObserver or is worth it, or whether you'd rather write your own abstraction. That's fine! At least we have a common point of reference, a shared vocabulary to compare and contrast things. And just because something is a web standard doesn't mean you have to use it. For the longest time, the classic joke about JavaScript: The Good Parts was how small it is compared to JavaScript: The Definitive Guide. The web is littered with deprecated (but still supported) APIs like document.domain, with, and s. Take it or leave it! Conclusion [I]n a sense there are nothing wrong with Web Components as they are only able to be what they are. It's the promise that they are something that they aren't which is so dangerous. Here I totally agree with Ryan. As I've said before, web components are bad at a lot of things - Server-Side Rendering, accessibility, even interop in some cases. They're good at plenty of things, but replacing all JavaScript frameworks is not one of them. Maybe we can check back in 10 years, but for now, there are still cases where React, Solid, Svelte, and friends shine and web components flounder. Ryan is making an eminently reasonable point here, as is the rest of the post, and on its own it's a good contribution to the discourse. The title is a bit inflammatory, which leads people to wield it as a bludgeon against their perceived enemies on social media (likely without reading the piece), but this is something I blame on social media, not on Ryan. Again, I find these debates a bit tiresome. I think the fundamental issue, as I've previously said, is that people are talking past each other because they're building different things with different constraints. It's as if a salsa dancer criticized ballet for not being enough like salsa. There is more than one way to dance! From my own personal experience: at Salesforce, we build a client-rendered app, with its own marketplace of components, with strict backwards-compatibility guarantees, where the intended support is measured in years if not decades. Is this you? If not, then maybe you shouldn't build your entire UI out of web components, with shadow DOM and the whole kit-n-kaboodle. (Or maybe you should! I can't say!) What I find exciting about the web is the sheer number of people doing so many wild and bizarre things with it. It has everything from games to art projects to enterprise SaaS apps, built with WebGL and Wasm and Service Workers and all sorts of zany things. Every new capability added to the web platform isn't a limitation on your creativity - it's an opportunity to express your creativity in ways that nobody imagined before. Web components may not be the future for you - that's great! I'm excited to see what you build, and I might steal some ideas for my own corner of the web. Related Leave a comment Cancel reply [ ] [ ] [ ] [ ] [ ] [ ] [ ] D[ ] This site uses Akismet to reduce spam. Learn how your comment data is processed. Recent Posts * Web components are okay * Improving rendering performance with CSS content-visibility * The continuing tragedy of emoji on the web * Reliable JavaScript benchmarking with Tachometer * Is it okay to make connectedCallback async? About Me Photo of Nolan Lawson, headshot Hi, I'm Nolan. I'm a web developer living in Seattle and working for Salesforce. Opinions expressed in this blog are mine and frequently wrong. Archives * September 2024 (3) * August 2024 (1) * July 2024 (1) * March 2024 (1) * January 2024 (1) * December 2023 (4) * August 2023 (2) * January 2023 (2) * December 2022 (1) * November 2022 (2) * October 2022 (2) * June 2022 (4) * May 2022 (3) * April 2022 (1) * February 2022 (1) * January 2022 (1) * December 2021 (3) * September 2021 (1) * August 2021 (6) * February 2021 (2) * January 2021 (2) * December 2020 (1) * July 2020 (1) * June 2020 (1) * May 2020 (2) * February 2020 (1) * December 2019 (1) * November 2019 (1) * September 2019 (1) * August 2019 (2) * June 2019 (4) * May 2019 (3) * February 2019 (2) * January 2019 (1) * November 2018 (1) * September 2018 (5) * August 2018 (1) * May 2018 (1) * April 2018 (1) * March 2018 (1) * January 2018 (1) * December 2017 (1) * November 2017 (2) * October 2017 (1) * August 2017 (1) * May 2017 (1) * March 2017 (1) * January 2017 (1) * October 2016 (1) * August 2016 (1) * June 2016 (1) * April 2016 (1) * February 2016 (2) * December 2015 (1) * October 2015 (1) * September 2015 (1) * July 2015 (1) * June 2015 (2) * October 2014 (1) * September 2014 (1) * April 2014 (1) * March 2014 (1) * December 2013 (2) * November 2013 (3) * August 2013 (1) * May 2013 (3) * January 2013 (1) * December 2012 (1) * November 2012 (1) * October 2012 (1) * September 2012 (3) * June 2012 (2) * March 2012 (3) * February 2012 (1) * January 2012 (1) * November 2011 (1) * August 2011 (1) * July 2011 (1) * June 2011 (3) * May 2011 (2) * April 2011 (4) * March 2011 (1) Tags accessibility alogcat android android market apple app tracker blobs boost bootstrap browsers bug reports catlog chord reader code contacts continuous integration copyright couch apps couchdb couchdroid developers development emoji grails html5 indexeddb information retrieval japanese name converter javascript jenkins keepscore listview localstorage logcat logviewer lucene nginx nlp node nodejs npm offline-first open source passwords performance pinafore pokedroid pouchdb pouchdroid query expansion relatedness calculator relatedness coefficient s3 safari satire sectioned listview security semver shadow dom social media socket.io software development solr spas supersaiyanscrollview synonyms twitter ui design ultimate crossword w3c webapp webapps web platform web sockets websql Links * Mastodon * GitHub * npm Blog at WordPress.com. * Comment * Reblog * Subscribe Subscribed + [86a4db] Read the Tea Leaves Join 1,247 other subscribers [ ] Sign me up + Already have a WordPress.com account? Log in now. * + [86a4db] Read the Tea Leaves + Customize + Subscribe Subscribed + Sign up + Log in + Copy shortlink + Report this content + View post in Reader + Manage subscriptions + Collapse this bar [b]