In my previous blog post about Web Components, I described several challenging problems still unsolved as of today. The feedback I received was surprisingly warm, and I was feeling excited to be mentioned by Alex Russell, one of the authors of the initial proposals. Some people called my notes a bit of an eye opener, while others mentioned even more problems.
Taking pink glasses off wasn’t the only goal I wanted to achieve though. My criticism was aiming to identify the pain points, and remind about the importance of consensus. The recent blog post by Jan Miksovsky about the history of HTML
<slot> element is a great illustration of the dead end where we could get same as 5 years ago, by pushing the proposals again.
Today I would like to expand my vision further and approach the same topic from a slightly different angle, by exploring the journey of Web Components towards the adoption so far and in foreseeable future. Same as previously, I rely on my personal experience and observations, so feel free to add your own notes, and correct me if you think I’m missing something crucial.
One more thing from the previous post I would like to remind you about is the upcoming “Face to face” (F2F) meeting regarding Web Components, with the participation of spec authors, browser vendors and users. Yes, there is a slot in the agenda dedicated to the real use cases. That’s good news, and I’m looking forward to see the meeting notes once they are published.
In early 2016, when I was making first steps with Web Components, there wasn’t that much examples. For me, the only source of inspiration at that time was Polymer Starter Kit. It has been changed a lot since then, and was replaced with the LitElement-based successor, PWA Starter Kit. But in a nutshell, they do the same: place
<my-app> component in
Wrapping a whole SPA into web component is the point where some people start to dream about throwing the frameworks away. At this very moment, in my opinion, they start falling into the pit of using improper patterns. Here I share the concern raised by Mattia Astorino. And from my previous post you already know how overusing Shadow DOM might strike back.
Taking the story further, the common feature every SPA needs is a client-side routing. And yes, people have been using Web Components for routing, too. In my former team, we were using
<app-router>, a vanilla v0 custom element from 2014 – and one of the first open source projects I ever have contributed to. At that time, I really liked its way of declarative routing.
But today it sounds ridiculous to me: first we run JS while registering a custom element, then each time user navigates we search matching routes from the DOM and run JS again. Am I wrong or is there an extra link in the chain? Declarativity is good per se, but trying to use HTML anywhere you need it, or in a way other people use JSX, is again a serious mistake.
The next framework-specific wheel we had to reinvent was a set of tools for loading data and managing application state. There has been a lack of best practices in this area in Polymer community. In short, we were supposed to use
<iron-ajax> to trigger API requests from the DOM, and then store the data again in the DOM – just to completely mess things up.
Someone would say, once you get locked into a web components collection, the tendency is to push it as far as you can. It can be explained by the fact that Polymer was heavily limited by HTML Imports (thanks to Mozilla for dropping them), and based on some assumptions from the “model driven views” concept, inspired by the dream about "declarative renaissance".
Talking about HTML, there is still a chance that HTML modules proposal will improve our developer experience and allow to use
<template> more. This is one of the areas where the Edge team is doing contributions to Chromium. While this could help creating Web Components in a better way, we shouldn't take those wrong ways of using them anymore.
Back to 2019, what are the better use cases for Web Components today? The first one you probably thought about are UI components, especially complex form controls. Surprisingly, Custom Elements are not currently designed to be picked up when submitting the standard
<form> HTML element. The form participation API proposal by Chrome team is expected to fix that.
When looking at the list of proposed updates to Custom Elements API, it seems to be a lot of work for browser vendors to agree and implement. Until then, we are unable use HTML form validation and submission without workarounds like
<iron-form> element. In my opinion, Web Components could reach a lot more audience once this issue is finally solved.
There are few other problems related to using Web Components in forms. One of those is broken form autofill for form elements within shadow trees in Safari. Another issue is that password managers like LastPass or 1Password do not support
<input> elements in Shadow DOM, as they presumably rely on global API, like
One more Shadow DOM concern we need to keep in mind is how it affects accessibility. This was described by Rob Dodson, but let me repeat in two words: shadow trees introduce the boundaries for IDs in the document, which affects ARIA attributes, like
aria-labelledby. That can sometimes make it harder to make the components both accessible and granular.
The similar issue with the IDs breaks the internal references in SVG, when using it inside Shadow DOM. As an example,
<use> element doesn’t work because of how
href references are resolved. Good news is that at least Safari has a solution supposed to fix that particular bug – which still has to be adopted by all the other browser vendors and then reflected in standards.
As you can see, at least two seemingly perfect cases to be solved with Web Components – namely, form elements and icons – have been more or less blocked for a while. In my opinion, having such lacking parts not covered for years (including the issues I already mentioned in my previous post) hurts the expansion of the new standards more than anything else.
So how could Web Components eventually reach the adoption? The browser support (at least, for basics) is now good. What we really lack today are real examples of using the native component model in production – preferably, in the big projects – and the best practices as a logical outcome of those. This in turn leads to a lack of trust to Web Components, and so on in a circle.
There is of course an example of YouTube, which is again a full SPA built with Polymer. But so far we observed mostly complaints about it being slow in Firefox and Edge and causing the decision to postpone the removal of V0 specs until Chrome 75. Finally, YouTube still doesn’t use native Shadow DOM, but a polyfill (and will most likely continue doing that in future).
Another case I would like to highlight is GitHub, which switched to using Custom Elements as part of the effort related to moving away from jQuery. What is especially great is how well Custom Elements fit the idea of keeping the content in HTML and progressive enhancement. See details-dialog and details-menu elements as really good examples of that philosophy.
Moving forward in search for the hype train where Web Components could in theory jump in, it appears that the today's motto are design systems. Reusability and being framework agnostic are the strengths we shouldn’t underestimate; that’s why Tesla has chosen Web Components. We shall see over time how much people consider making the same bet.
Enterprise companies are potentially the strongest audience for Web Components, and that’s what we see from State of JS 2018 survey – check the numbers for Polymer. Let me mention ING and its team of open source enthusiasts who created open-wc, and Red Hat sponsoring the PatternFly elements library among the examples of such big companies.
One of the promising paths would be using Web Components to build an architecture and to embed parts of the application. This concept is known under the name of Micro Frontends. It can be questionable to what extent should we use Custom Elements as “spicy iframes”. But at least it’s good to keep in mind that DOM and CSS aren’t necessarily global anymore.
Back to where we started, let me again emphasize that Web Components are not a silver bullet. They will not replace JS frameworks, despite some people claim the opposite, or even start saying bye to React. In fact, such biased statements usually hurt more than help. That's why I wanted to add my 5 cents to the ongoing discussion and drive it in the right direction.
The Web Components are safe to use today, regardless of all the unsolved issues requiring further standardization, which I have tried to systematize. Forewarned is forearmed, and I hope you are brave enough to not even fear the Chrome crashes or rendering issues, which have affected few stable versions. Some things need to stabilise, but it’s not that scary after all.
The lack of expertise among the developers, admitted by David Flanagan during the recent holy war regarding the MDN web docs page header being rewritten in React, doesn’t sound a really valid excuse to me either. As long as most of frontend teams stick to well known stack, how would we adopt for example CSS grid layout, or ES modules supported natively as well?
So let’s accept the challenge and take it as a chance to be a pioneer, building completely new things with the native component model which the web platform offers. Now in 2019, it’s time to give a try to Custom Elements and Shadow DOM. They might not be “the next big thing” by themselves, but rather solid foundation the next big thing could be built upon.
I recommend considering Custom Elements, Shadow DOM or both, depending on the actual needs, when starting a new project or refactoring the existing one, to anyone interested in the long-term solution. Also, I would love to hear about the lessons you learned with Web Components – including your own pain points, as I realise that it’s not all roses.
Finally, I would like to encourage anyone to contribute to the “awesome” list named Web Components: the right way. As I previously announced, I’m the maintainer of that project and try to do my best in order to make it a more or less full and up-to-date knowledge base. And, as usual, I’m very grateful to hear your feedback and any comments regarding this blog post.