Are web components worth it?

Transcript
  1. Surma:Welcome to a brand new episode of OTMT, which stands for Off the Main Thread. We have more
  2. Surma:tangents than content. And that's how we roll. I am Surma. And welcome. Yeah. At this point,
  3. Jake:And I am Jake, and welcome!
  4. Surma:it is customary to thank Shopify for letting us record this and giving us money to have
  5. Surma:this out on the web for you all to listen to. So thank you, Shopify.
  6. Jake:And ultimately, you know, money so we can just eat and stuff. I mean, that's not for
  7. Jake:the podcast, that's the job, really. But you know what? It's nice!
  8. Surma:Eating is nice. Who would have thought? Speaking of, like, very important life advice. I was in
  9. Jake:Uh-oh. Uh-oh. Oh, sorry, hang on. Do you know what? Because you're in the hospital, I was
  10. Surma:the hospital because I'm a smart boy. We've been trying to do some upcycling,
  11. Surma:and we had some bedside tables, and we were like, they're too tall.
  12. Jake:looking for, you know, I was thinking of you're going to be having some kind of major accident,
  13. Jake:which maybe you are. So when you said upcycling, my visual brain just tried to visualize you
  14. Surma:That's how he broke both legs. No, like, we, yeah, no, furniture upcycling.
  15. Jake:on a bike trying to cycle up a building, and I was like, well, that'll do. Yeah, of course.
  16. Jake:Of course. Of course. Yeah. I do a cross-cycling, and you know what? That's been okay for me
  17. Jake:so far. Anyway, sorry, you're upcycling!
  18. Surma:Yes, I'm upcycling. And we're like, you know, we could get new ones and try to sell these. Or
  19. Surma:we try to do the DIY thing, and we saw some legs, and we paint them a new color. And I am
  20. Jake:I was going to say, you sawed off the wrong legs, and straight to hospital!
  21. Surma:proud to tell you that the sawing is not the origin of the injury.
  22. Surma:That would have been quite impressive. No, we just, you know, it went really well. We
  23. Surma:sawed the leg off. We sanded them down. We painted them, like, for a first DIY. Well,
  24. Surma:not first, but, like, nothing I've really, like, completely done before. I was quite okay with it.
  25. Surma:And so they were drying. It was all done. I was just cleaning the brushes. And I had some white
  26. Surma:spirit to clean the brush more effectively. And I was putting the brush into a little, like,
  27. Surma:basically a little glass with white spirit swirling around. And I was a bit careless,
  28. Surma:and it, like, splashed upwards and straight into my eye. And I was like, oh, is it in my eye? Did
  29. Surma:I close my quickly enough? Because it felt fine. Like, there was no sensation. It was just like,
  30. Surma:obviously, the smell of white spirit on your skin isn't great. So I just was like, I'm gonna finish
  31. Surma:cleaning the brush. And then I'm gonna start googling what you need to do. Like, on the bottle,
  32. Jake:Uh-oh. Which is hard, hard work. 20 minutes? What? 20 minutes? Oh, would your eye get all
  33. Surma:it didn't say anything. It said what you should do if it's on your skin, when you drink it,
  34. Surma:when you inhale it, but nothing what to do when you get it in into your eye. And so I was googling.
  35. Surma:And while I was googling, I noticed that my eye started to feel a bit weird. Online, it said,
  36. Surma:you need to, like, wash your eye under running water, like, rinse your eyeball for, like, 20
  37. Surma:minutes. Yeah. So and
  38. Jake:wrinkly? If you wash your hand for 20 minutes, it gets all wrinkly. I suppose your eye would
  39. Jake:get the same. Sort of look like a sort of testicle with a pupil. No. Oh.
  40. Surma:same. Absolutely. It was the eye testicle. It was where I ended up. I guess I don't want to
  41. Surma:lose my eyesight or anything. And so I went into my shower and I laid down and I used my shower
  42. Surma:head and kind of, like, hold my eye open and rinsed my eyeball. And then my partner came up
  43. Surma:and was like, why are you lying in the shower in your underwear and rinsing your face? And so I
  44. Surma:explained it. And she was like, was like, kind of freaking out. No, no, stay calm. But it does say
  45. Surma:ask for medical advice, call 111, the not super emergency thing. And so while I was there in the
  46. Surma:shower with a shower head in my eyeball, she put the nice lady from 111 on speaker and we talked
  47. Surma:it through and she was like, you did the right thing, but it is quite aggressive and you need
  48. Jake:Before you get to that, I do feel like, so people on the outside might not know this,
  49. Surma:to go to the hospital just just to be safe. Not life threatening.
  50. Jake:but 111 is the number you call when your arm's a bit damaged. It's not. So 999 is the emergency
  51. Surma:How deep is your injury? Measure it. And the number of centimeters is the number you call
  52. Jake:services. It just feels like there's a real opportunity there to do the full range. Yeah,
  53. Surma:for three centimeters. Call three, three, three.
  54. Surma:I mean, I was going to say that.
  55. Jake:a 666 situation. Oh, hang on, that might be something else.
  56. Jake:Yeah, okay, hang on. I think we've just solved why they don't do that.
  57. Surma:Yeah. And last time I was in the hospital, I was in the hospital for a week.
  58. Jake:Okay, sorry. Anyway, so you're hospital bound, right? Is that what I understand?
  59. Surma:Yeah. And last time I was in the hospital, it was, you know, the NHS is stretched thin and I was there
  60. Surma:from 10 p.m. to 6 a.m. last time. And that was a horrible experience just because you had to stay
  61. Surma:awake. But this sounds like, OK, I thought that you stay here. You look after the dog. There's
  62. Surma:no point for the two of us being bored to death again in the hospital. I'm going to Uber there
  63. Surma:and going to have it sorted out. And so I got myself an Uber. And while I was in the Uber,
  64. Surma:while I was in the Uber, my partner was like, please tell me, like, keep me updated. I'm a bit
  65. Surma:anxious. I also may have taken some pictures on your phone.
  66. Surma:And so while I was in there, I looked at my camera roll and there I am just lying in the
  67. Surma:shower in my pants with a shower head in my face. And I was like, you know what? Fair play.
  68. Jake:Oh, we'll link to those in the description.
  69. Surma:Well, fair play by her to just seize the moment while waiting for the one on one day to pick up.
  70. Jake:Absolutely.
  71. Surma:But in the end, it was actually fairly short, like the hospital for some reason wasn't busy.
  72. Surma:I got my turn really quickly to be triaged. And she did a quick, you know, litmus paper,
  73. Surma:which changes color depending on whether the solution is acidic or.
  74. Jake:They put that in your eye?
  75. Surma:They had put paper in both my eyes to see if it has the same acidity because my left eye was
  76. Jake:Oh, that's clever.
  77. Surma:unaffected. They say if it's the same acidity, you probably washed most of it away. Weird,
  78. Surma:but clever. And so in the end, I got a couple of eye drops and an ointment just because it turns
  79. Surma:out washing your eyeball for 20 minutes with just straight up water, not even saline solution,
  80. Surma:will irritate your eye a bit. I'm proud to report no eyesight was lost.
  81. Jake:Yeah, yeah.
  82. Jake:It can happen. I remember when I was a young teenager, there was this new deodorant came
  83. Surma:No consequences, but I felt like a proper idiot,
  84. Jake:out called Physiosport, and there'll be a section of people who know what I'm talking about. It was
  85. Surma:just cleaning a brush and splashing white spirit into my eye. So, yeah.
  86. Jake:one of those kind of like, you know, powder. It's one of the sort of early sort of aerosol,
  87. Jake:but powdery. You know what I mean? It's like, you know, it's one of those, you know,
  88. Jake:like, powder. It's one of the sort of early sort of aerosol, but powdery. You know what I mean?
  89. Surma:The one that leave nice white streaks on everything.
  90. Jake:Yes, exactly that. They were giving out free samples. And I had one of these,
  91. Jake:I just sort of had it on my desk. And it's got like a sort of click,
  92. Jake:like rotation lock, it kind of locks, you know, the thing, right? Anyway,
  93. Jake:so I had that on my, you know, it's just sort of, I was just playing some games or,
  94. Jake:you know, coding or something. And I sort of play around with things that are on my desk.
  95. Jake:And I just sort of picked up this Physiosport thing. And I just sort of like tapped it against
  96. Jake:my cheek bone. And I thought it was locked. And it wasn't because when I did that, it's when
  97. Jake:and then I just, I just sort of froze because I panicked. And this like, I was at point blank
  98. Surma:Yeah.
  99. Jake:range of my eyeball pretty much, but because it was angled upwards, I got away scot-free.
  100. Surma:We.
  101. Jake:Now there was white powder on the end of my eyelashes. That's how close it was. And I just
  102. Surma:Wow.
  103. Jake:think of like, that was, Jake, that was very stupid. I like, I know we've gone from a couple
  104. Jake:of episodes ago, stories about me being under a train. And now that I feel like I've actually
  105. Surma:There's a pattern made. They do say to women here in the UK that they should have a deodorant
  106. Jake:been quite lucky. Oh, yeah.
  107. Surma:with them as a way to defend themselves because pepper spray is not allowed to be carried. Well,
  108. Surma:in Germany, as a woman, you can get pepper spray and have it in your handbag as a self-defense
  109. Jake:If you have pepper spray and deodorant, there's always the risk you mix them up.
  110. Surma:tool. So yeah, deodorant is apparently the next best thing. So you almost did that to yourself.
  111. Surma:Well done. Yeah, I mean, you don't want to smell like pepper spray under your armpits, I think.
  112. Jake:I imagine that would irritate you. Should we talk about the web?
  113. Surma:Let's talk about the web. What are we talking about today, Jake?
  114. Jake:I want to ask the question, are web components worth it?
  115. Surma:Oh, that's gonna be such a good title.
  116. Jake:Oh, yeah. You see this, this is title first authoring. Absolutely.
  117. Surma:Yeah.
  118. Jake:So let's dig in. Right. And I want your opinions on this as well, because it's something we've
  119. Jake:sort of both worked in and around. So, okay, let's start from the start. Web component is a sort of
  120. Jake:umbrella term for a bunch of stuff like HTML, custom elements, the shadow DOM and template
  121. Jake:elements, and maybe some other kind of CSS features fall under that as well. At a low level,
  122. Surma:Yeah.
  123. Jake:it gives you a number of abilities that the browser already has. So you put an input element
  124. Jake:on the page, you know, it has its own set of attributes on sets of properties, custom elements
  125. Surma:Yes.
  126. Jake:let you hook into this. So you can have your own tags, your own associated classes by classes.
  127. Jake:Classes by classes, I mean, like a JavaScript class, a good interface, a prototype, that kind
  128. Surma:So
  129. Jake:of thing. And you also get a load of little callbacks to tell you when attributes have
  130. Jake:changed and when an element's been connected to the DOM and disconnected from the DOM.
  131. Jake:I would say I don't like those. I don't like that as an API design.
  132. Jake:I don't like that it's part of the public API. You know what I mean?
  133. Surma:I agree that there are some design choices for the custom elements API that I'm not
  134. Surma:a huge fan of. As a principle, I like custom elements exposing the capabilities that the
  135. Surma:native HTML tags are already using. But I'm guessing they didn't actually at the time,
  136. Surma:I think like behavior was specified, not how it's implemented. So I'm guessing there wasn't just
  137. Surma:let's just expose what the browsers already have, because it would have been wildly different across
  138. Surma:browsers that I needed to design something. And some is fine. I think some is a bit short-sighted
  139. Surma:like the fact that custom element registry isn't namespaced, which makes
  140. Jake:Oh, yeah, yeah, yeah.
  141. Surma:librarification a bit complicated. Yeah, the attribute changed callback seems a bit weird,
  142. Surma:maybe even unnecessary, because you could just use like a mutation observer on yourself, I suppose.
  143. Surma:I don't know. Yeah.
  144. Jake:I think the difference is the timing. I think attribute change callback is synchronous,
  145. Jake:whereas the mutation observer equivalent is microtask bound. But even then, like,
  146. Jake:well, it's called the revealing constructor pattern. And this is the one, if you do new
  147. Surma:Yeah.
  148. Jake:promise, you pass it a function, and you're given the resolve and reject functions inside there.
  149. Jake:And that means, like, you know, you've kind of got private access to those functions.
  150. Surma:It streams the same pattern.
  151. Jake:Well, with streams, no, it's not quite the same pattern, because you...
  152. Surma:Because you get access to the controller inside the constructor object.
  153. Jake:Yeah, that's right, actually. With streams, you pass an object with callbacks,
  154. Jake:but obviously those callbacks are private. And then in those callbacks, you get given the
  155. Jake:controller. So it is, yeah, it is a very similar model. I would have thought, like, the super call,
  156. Jake:because you've got, you know, my custom component extends HTML element,
  157. Jake:and then in your constructor, you call super. And I think that's maybe where they could have done
  158. Jake:the same pattern. I imagine the argument was, you know, it's better to have it on the prototype,
  159. Jake:because then there's only one instance of the function across all the elements where,
  160. Jake:you know, if you're doing it in the constructor call, you're likely to have lots of instances.
  161. Jake:Anyway, let's not get bogged down on that. Because the other thing that you can do,
  162. Jake:think about input type color, input type range. There's a lot of interface there that appears
  163. Jake:when you put that on the page. It's one tag in your page, but there's a lot of moving parts,
  164. Jake:interactive, and all of that sort of stuff. Shadow DOM is what explains this in a way,
  165. Jake:because it gives you the same abilities. You create this little kind of hidden DOM
  166. Jake:within the regular DOM that's sort of kind of hidden, kind of not. And this is where you put,
  167. Jake:you know, you build up your interface. And styling is also scoped within that as well.
  168. Jake:I fundamentally like this. You know, apart from my little complaints about the API and whatever,
  169. Surma:Yes.
  170. Jake:I like that it's explained some of the platform that was previously unexplained. Like how does
  171. Jake:an input have all of this bits of interface associated with it? And it lets us do the same
  172. Jake:thing with our own stuff, you know. This whole thing was developed by Chrome, like in the open
  173. Jake:at the W3C, but it was really just Chrome. And this was in the early 2010s. And they shipped it.
  174. Jake:And a few years later, Safari came along and went, well, we're interested in this, but we want
  175. Surma:That was Custom Elements v.0 versus...
  176. Jake:a bunch of changes. So then there were breaking changes. And that was like in the mid 2010s.
  177. Jake:V1. Yeah. And I, you know, I think it was actually fair for, I mean, you could argue it either way,
  178. Jake:like Chrome shipping something that really hadn't been closely looked at by other browser vendors
  179. Jake:was not great. But then on the other side of that is like, it's sort of bad that other browser
  180. Surma:Yeah.
  181. Jake:vendors could hold the web back by just not taking part, you know. So whatever, I don't know quite
  182. Jake:where I sit on that. But I think most of the changes that Safari wanted are going to be
  183. Surma:Was Shadowroot, like Shadow DOM, part of the initial design?
  184. Jake:are good. Don't ask me too much what they were. Like, it's actually really hard to find the
  185. Jake:original web component specs, you know, a few differently named functions. I think there
  186. Jake:was some things like where you could create many shadow routes for one element at some point. Anyway.
  187. Jake:Yes, it was. It's all sort of developed as a kind of separate feature. And there was also things
  188. Surma:Oh, that was a thing, yes.
  189. Jake:like HTML imports, which like just died off really, which was kind of like a single HTML
  190. Jake:file, which had the template and the behavior, the single file for a component.
  191. Surma:In retrospect, not really something that I miss, I have to admit.
  192. Surma:Because I feel like one of the things, and maybe you get into this, but custom elements
  193. Surma:are really just that.
  194. Surma:Web components and custom elements, by extension, are not really, for me, a primitive to substitute
  195. Jake:I absolutely agree. And I think this is where things went a little bit wrong. We both worked
  196. Surma:components as we call those components in React.
  197. Surma:It's really individual elements, and I feel like once you go into higher-level components,
  198. Surma:it gets unwieldy, and I'm not sure they're well-fit for that.
  199. Surma:Oh, are you gonna use the platform, me?
  200. Jake:at Google at the time, the narrative was always there. I don't know, it always felt
  201. Jake:used as the user platform meme. But I felt like, I don't know, as a DevRel team, we picked up a
  202. Jake:lot of flack saying like, oh, you know, Google's DevRel team is always pushing web components.
  203. Jake:And I was kind of looking around going, I don't think we are. We've got like one guy kind of
  204. Jake:working on it. And I think this is mostly it was a different team. This is the Polymer team. And
  205. Jake:they were sort of pushing their library and web components as a competitor to React. And I agree
  206. Jake:with what you just said. I don't think I think these are different things. Like, we did a whole
  207. Jake:show on bringing React to the web and kind of how it works. But like, it's an abstraction of the web
  208. Jake:platform. Whereas web components are exposing new bits of the platform. I think that's the sort of
  209. Jake:in React, you're saying create me a DOM tree that looks like this. I call them DOM orchestration
  210. Jake:frameworks. And no one else does, but fine. Whereas like web components is like, here is
  211. Jake:an HTML element. Here's what to do when this is created. And when this is modified. And they're
  212. Jake:similar. But yeah, I agree that they're different, especially when you get onto the sort of larger
  213. Jake:things. And I think one tell there is the HTML was created, which was to do the DOM orchestration
  214. Jake:thing with web component, like in and around web components. Another argument is what about
  215. Jake:performance and a lot of React sites are badly built. I mean, they just are. But it was worse
  216. Surma:And so far, Preact Compat Mode lets me use mobile libraries from the React ecosystem
  217. Jake:back in the 2010s, right? But I think especially these days, I don't think there's anything about
  218. Jake:the DX that makes React fundamentally bad. And I think that's why at Google, we built stuff with
  219. Jake:Preact. I think React is way heavier than 99% of sites using it need. And you know, for 50k versus
  220. Jake:3k or whatever, you know, you can do this stuff in Preact.
  221. Surma:that I want.
  222. Surma:So it's really tough for me to justify using React over Preact, unless if you have a cross-platform
  223. Jake:But even then, I feel we kind of managed to convince people at Google that, look, yeah, you can build
  224. Surma:app where the same components run in React Native or something.
  225. Surma:But yeah, I just grab Preact with Compat Mode if I want to use a library.
  226. Surma:It's really good.
  227. Jake:stuff with Preact and it'd be fast. And so people like, okay, so React slow, Preact fast. It's like,
  228. Jake:well, no, I don't think it's that either. It's like, well, you can build fast stuff with React.
  229. Surma:Yeah, I think, actually, I would assume that if we were to say, like, Squoosh and have
  230. Jake:So yeah,
  231. Surma:it rendered with React rather than Preact, it would have the same runtime performance.
  232. Surma:Loading performance would get worse because it's a bigger library.
  233. Surma:But in terms of like, I don't think there's fundamental speed benefits in how Preact manages
  234. Surma:its VDOM and the diffing and the reconciliation over React.
  235. Surma:I think there's probably a couple of things that are, some code might break because Preact
  236. Surma:actually lets you add arbitrary event handlers and kind of stuff, which React doesn't.
  237. Jake:Yeah, so like first interaction time would go up on Squoosh just because we're going from like what 20k to 60k just because of the size of react. But yeah, ultimately it's fast after that. And even then, like compared in most sites, that's a drop in the ocean, right? And because the reason these things get slow is because people actually they lose control of their builds. Like that's what happens.
  238. Surma:I think it's just about to finally get fixed.
  239. Surma:But yeah, I think React is not inherently slow or inherently slower than Preact.
  240. Surma:Thanks for watching.
  241. Jake:Like that's where the slowness comes in. It's loads of third party libraries, different versions of the same third party library that. And I think Preact sites are probably faster as a whole, because the kind of people who cared enough to pick Preact over React care enough to be looking at their build more. And then so yeah, HTML actually has some nice tricks up its sleeve in terms of how it does the diffing. I don't think it's really diffing, but that kind of equivalent.
  242. Jake:But then we've got signals and Preact as well, which are, you know, fun, fun tricks. So I think that's a, yeah, performance wise, I don't think there's a big difference, really. So what about the DX, right? So we've got web components compared to React and all similar prop based frameworks.
  243. Jake:Well, if you're writing a web component, you have to care about properties versus attributes, which we talked about a couple of shows ago. I've got a blog post where I dig into that a bit more. If you're doing a React component, all you care about is the props. Whereas a custom element has get as setters, has like methods and things. If you want things to work straight from just HTML, then you're limited to attributes, which are strings or like structures of inner elements for your data.
  244. Jake:A bit like how the select element has an inner structure of option groups and options that you can, you can do that as well. You need to care about elements disconnecting and reconnecting, which on the surface sounds similar to mount and unmount in React, but they're actually different because with a real HTML element, you can disconnect it and you can put it back or you could put it somewhere else, but it is the same one.
  245. Surma:I've actually completely forgotten about those hooks in React components because the
  246. Jake:Yeah, that doesn't happen in React. If an element moves around, it isn't unmounted. Like unmounting is this is going away forever and mounting is this thing is new.
  247. Jake:Yeah, that's what the equivalent is now is use effect with a empty array.
  248. Surma:functional components have become so much the standard with hooks instead of using these
  249. Surma:lifecycle callbacks that I forgot that React even exposes that, but yeah, you're right.
  250. Surma:Returns a cleanup function.
  251. Jake:Yeah, and with a cleanup function and that's your mount and unmount. Yeah, sure. Elements can have methods, which is, you know, a thing. You can kind of have methods on things in React, but they recommend against it. Shadow DOM gives you scoped CSS, but frameworks give you equivalents with like CSS modules.
  252. Surma:I guess most of the time in other hooks, you just create hidden input fields for that,
  253. Jake:And there's also new CSS features like scoped CSS and CSS layers and resets, all of that sort of stuff. One of the nice things is custom elements can be genuine form inputs, which I like, and I think it's a little less known. Like you can create your custom elements, which when the parent form is submitted, fire a submit button or whatever, your custom element will tell the system what its value is, what its name is, what its value is.
  254. Jake:Exactly. Yeah, it's pretty, pretty easy. Just put an input type hidden there and there you've got the ability to do a name and a value. You couldn't put file data in there. It's probably the only bit that's different, I think. But then there's all kinds of sort of limitations like custom elements cannot be forms. They can be form fields, but they can't be forms.
  255. Surma:but yeah, that's kind of what I'm doing.
  256. Surma:Oh, I didn't know that.
  257. Jake:Yeah, so there is a syntax. You would do form and then you would have the as attribute. And I'm losing confidence that it's the as attribute because it, yeah, I was like, is it as or is it is?
  258. Surma:Well, either way, this is the part where you could subclass existing... it is?
  259. Jake:It is. Yeah, it is. It is not as it is. Is it as or is it is? It is is.
  260. Surma:I mean, this should be the episode title.
  261. Jake:It is is.
  262. Surma:This is where you can subclass existing HTML elements.
  263. Surma:All custom elements have to inherit from...
  264. Surma:Are classes that inherit from HTML elements, but actually I think for the longest time,
  265. Jake:Right.
  266. Surma:you could also subclass from HTML button element if you wanted to get all the functionality
  267. Surma:of button and just add some stuff and then you would use this syntax.
  268. Surma:However, I think Safari never supported it and still doesn't, but I'm not sure on that now.
  269. Jake:Correct. WebKit said no. They fundamentally do not like this as a system. And I kind of agree with, you know, when you have a custom element and it's like my dash select or whatever, going from that to form with an as attribute of as my form or whatever is.
  270. Surma:Maybe the as syntax is not great, but shouldn't my... like if I write a custom element called
  271. Surma:my input field, why shouldn't it be able to get all the existing work of an input field
  272. Surma:and I just want to add stuff?
  273. Jake:I think it was seen as being too hard to integrate with the parser and who owns the Shadow DOM in that case.
  274. Surma:Oh.
  275. Jake:So, which is why for input fields, you just create a custom element, but you use the element internals API to say, by the way, I'm actually a form field. I think there's a static property as well to say that your form associated.
  276. Surma:I see.
  277. Jake:Yeah, we don't have the equivalent for the form element itself, because if you put a form in a Shadow Root, it will handle inputs that are inside it that are also in the Shadow DOM, but not inputs that are slotted, that are kind of part of another Shadow DOM or the light DOM.
  278. Jake:I do agree, actually. And I do wonder if this stuff was kind of three engine collaboration. I wonder how much better we could have got.
  279. Surma:Right, I do sometimes feel that Shadow DOM introduced complexity and unintuitive behavior
  280. Surma:that to this day, I'm actually not always on board with.
  281. Surma:I mean, I mean, I understand kind of because you do want to somehow find a way to explain
  282. Surma:how does the video tag show controls that are clearly like buttons and divs and sliders,
  283. Jake:Yeah, so let's say you're creating a custom select element, but you want the options to be in the form field.
  284. Surma:but they do not appear in the DOM.
  285. Surma:Like your normal DOM is just a video tag element.
  286. Surma:So I kind of can see how that gave birth to Shadow DOM as an explanation of what that is.
  287. Surma:But yeah, there's so much weirdness going on in these kind of things where you want your element
  288. Surma:to be a form.
  289. Surma:So you put your form in the Shadow DOM and then you slot things in and even the slots
  290. Surma:are already a bit confusing, I have to admit.
  291. Surma:But then it doesn't behave as you expect.
  292. Surma:It just, it's a lot.
  293. Jake:You want the options to be able to contain DOM tree stuff, like a video, an icon, or even just emphasis and strong tags.
  294. Surma:A video.
  295. Jake:And so when the select is collapsed, you want to just render the selected option there.
  296. Jake:But when it's opened, you want to show all of the options in their order and in their groups, if you have groups or whatever.
  297. Surma:Yeah.
  298. Jake:You can't do that with web components, because you've got the equivalent of the option element there, and you've got slots, but you can't slot elements that aren't direct children of the element.
  299. Surma:Yeah.
  300. Surma:Yeah.
  301. Jake:And whereas in this case, you might be wanting to take that option, which is inside a group with other options, and you're wanting to put that kind of as the selected item.
  302. Jake:You just cannot do that, because it's not a direct child.
  303. Surma:It kind of seems to me this is like this really should like the way you map your light DOM
  304. Jake:There is a programmatic way, but you can only pick elements that are direct children of the host.
  305. Surma:children into your Shadow DOM should not be declarative.
  306. Surma:There should be a programmatic escape hatch.
  307. Surma:But why?
  308. Jake:Yeah, well, okay. I have been exploring this, and it isn't straightforward, because there can be cases where it's not about iframes, it's about events.
  309. Surma:Don't tell me it's about iframes.
  310. Jake:And you could end up with, if you're picking something that's quite deep in the tree, to be somewhere else.
  311. Surma:Yeah.
  312. Jake:The event has to travel through the light DOM, and then through the shadow DOM, but then it's going to appear out kind of deeper within the light DOM, and then it's...
  313. Surma:And basically skipped out either skipped elements in the light DOM in the bubbling process or
  314. Jake:Repeat.
  315. Surma:kind of has to reset further down.
  316. Surma:Yeah, I see that.
  317. Jake:Repeating is more the risk.
  318. Jake:But I think all of this is solvable. I really do. And I filed an issue, because I think this would be really useful.
  319. Surma:Yeah.
  320. Jake:But I recognize that it is not like, you know, what you're doing, come on, just ship it.
  321. Jake:It's not an easy problem. I can see why they didn't do it, but I still think we can fix it.
  322. Jake:The other issue with Web Components is the server rendering story, right?
  323. Surma:Yes.
  324. Jake:Before your JavaScript loads, your custom element is going to render as nothing or broken.
  325. Surma:I think the first solution was the unresolved pseudo selector in CSS, which would allow
  326. Jake:Is that a problem?
  327. Surma:you to apply styles to tags whose custom elements definition had not been loaded.
  328. Jake:Yes.
  329. Surma:Yeah.
  330. Jake:Yeah, and I think that's okay for things like form fields, buttons, things like that.
  331. Jake:You can probably use a small bit of CSS to reserve the room needed for that component, so you don't get a layout shift when the real thing loads in.
  332. Jake:And I think it's good in a way, because it means you'd just be reserving space for the element until it is interactive.
  333. Jake:And I think that's one of the big problems we see with frameworks today.
  334. Jake:Like, I think it encourages you to server render an interactive thing which is not going to work.
  335. Jake:You're going to have buttons that don't work until the rest of the JavaScript is loaded.
  336. Surma:Yeah.
  337. Jake:Anyway, whatever. But you're really stuck with things like...
  338. Jake:I try and divide it between, you've got these interactive components, but then you also have these HTML macros.
  339. Surma:Yeah.
  340. Jake:A grid component, it's just an HTML macro, really.
  341. Surma:Yeah.
  342. Jake:As in a React grid component, it's just going to spit out a div with some other divs and a bit of CSS.
  343. Jake:It doesn't do anything beyond that.
  344. Surma:And you know what that that is a very common pattern on native platforms like both iOS
  345. Surma:and Android have this all have kind of like an XML or an XML like syntax to define the
  346. Surma:layout hierarchy of your view of whatever is on screen.
  347. Surma:And they usually have like now actually flex and grits are quite popular.
  348. Jake:Yes.
  349. Surma:They're like what was there since this has now kind of propagated to native platforms
  350. Jake:Yeah, React Native has Flexbox as a component, which is trying to be as CSS-y as possible or match the CSS definitions of these things.
  351. Surma:to talk about and baby that's there.
  352. Surma:But you have these components that just lay out their children according to these algorithms
  353. Surma:and they're just elements in a native plan.
  354. Surma:That's fine.
  355. Surma:And on the web, it feels weird.
  356. Surma:Maybe it shouldn't.
  357. Surma:I don't know.
  358. Surma:But I mean, this feels like something.
  359. Jake:But yeah, it doesn't work as a custom element.
  360. Jake:Unless you can ensure that your custom element's JavaScript has loaded before this tag appears,
  361. Jake:which normally means loading it as blocking JavaScript.
  362. Jake:Exactly that.
  363. Surma:Oh, it doesn't work as a component with unresolved styles because the styling depends on the
  364. Surma:attribute values and you can parse.
  365. Surma:Yes, that's an issue.
  366. Jake:And of course, you can have CSS that targets the different attributes.
  367. Jake:But at some point, it doesn't scale.
  368. Surma:True.
  369. Surma:And now that I think about it, to an extent, you know, if you want like for, say, flex
  370. Surma:direction, totally doable.
  371. Surma:If this container has an attribute flex direction with value column, you set flex direction
  372. Surma:to column.
  373. Surma:What would make this better?
  374. Surma:You're right.
  375. Surma:It's still probably not scalable to the end, but it's better if the stupid attribute function
  376. Surma:in CSS would work.
  377. Jake:The ATTR, yes.
  378. Jake:And you're just sort of piping an attribute through to CSS.
  379. Jake:Yeah, that would be pretty good, if they are one-to-one, absolutely.
  380. Surma:I mean, we're probably you would have to do like string patination because if you did
  381. Surma:like, oh, no, I guess you would still use the read.
  382. Surma:Like if I was thinking that if you had like a grid component and you would say grid template
  383. Surma:rows equals repeat blah something, it's just again, it's the entire string just taking
  384. Surma:copy paste into CSS.
  385. Surma:So it would work.
  386. Jake:Yes, you can, for the content.
  387. Surma:It would be quite powerful.
  388. Surma:I have often found myself wishing that Attr as a CSS function would be supported for more
  389. Surma:than just I think on pseudo elements before and after.
  390. Surma:I think you can use them.
  391. Surma:Yes, for content, exactly.
  392. Jake:It would be nice, because maybe it could be used to explain how the SVG presentational attributes work.
  393. Jake:Maybe.
  394. Jake:But the other solution we have for this is declarative Shadow DOM.
  395. Surma:I think this is literally this is my reaction to it.
  396. Surma:And I have to admit, I haven't even looked at what that is in a long time.
  397. Jake:It's a template element with an attribute on it, which says, make me the Shadow DOM for the parent element.
  398. Surma:And the browser will automatically create a shadow root on the element.
  399. Surma:The template tag is in put the contents of the template tag into the shadow root even
  400. Jake:Yeah.
  401. Surma:before the custom element is necessarily loaded or resolved.
  402. Surma:It's just like a template tag you put under div because you can just put a shadow root
  403. Surma:under a div as well.
  404. Surma:
  405. Jake:Yeah, I'm pretty sure this will work just on any element.
  406. Jake:But it does need to go in every element.
  407. Jake:So for every grid instance of your grid web component, you would be putting in this template,
  408. Surma:I was going to say, which is silly, but I guess that's slightly better.
  409. Jake:which would include the CSS that it needs.
  410. Jake:And yes, you could add import the CSS to djupy.
  411. Jake:Yeah, it means that you're having a separate CSS file for each component, which is oof.
  412. Jake:So this is the thing.
  413. Surma:But again, also same problem, right?
  414. Surma:You still don't get access to the attributes on the element that you're being.
  415. Surma:Oh, no.
  416. Jake:What you would end up doing is, because as the server rendering tool, you know what attributes you're writing,
  417. Jake:you will therefore know which declarative Shadow DOM to create for that first render.
  418. Jake:Which means that you now need to have a build script.
  419. Surma:Which makes the at imports trick moot because you know,
  420. Jake:Well, no, you can still import your CSS.
  421. Surma:Also, you would basically just set the properties that the attributes correspond to and then at imports the rest and then the cascade will take care of merging the stars create. I guess you could even use CSS variables. Right? Like you could just the server renders out.
  422. Jake:That should be fine.
  423. Jake:Because you are just defining the same Shadow DOM that you would with script.
  424. Jake:But you're just kicking it out from the server.
  425. Surma:Also, you would basically just set the properties that the attributes correspond to and then at imports the rest and then the cascade will take care of merging the stars create. I guess you could even use CSS variables. Right? Like you could just the server renders out the batch of CSS variables as inline styles and it imports the generic styling and then things start working together. Okay.
  426. Jake:Oh, exactly.
  427. Jake:Because you would use class names, right?
  428. Jake:And just as you do if your normal Shadow, it should be one for one.
  429. Surma:Also, you would basically just set the properties that the attributes correspond to and then at imports the rest and then the cascade will take care of merging the stars create. I guess you could even use CSS variables. Right? Like you could just the server renders out the batch of CSS variables as inline styles and then things start working together. Okay.
  430. Jake:But it means that you're going to have to have a special build script that outputs those.
  431. Jake:And then it's kind of like, I've now lost the simplicity of custom elements, which is just put a tag on the page.
  432. Jake:I now have to have a full build system behind it.
  433. Jake:And it's getting like, well, what am I really gaining compared to?
  434. Surma:To be fair, you also need a custom render script for any UI framework. You want to serve a render.
  435. Surma:Yeah.
  436. Jake:I guess one of the selling points of custom elements, it could be like, well, you don't need that.
  437. Jake:You don't need a complex build system.
  438. Jake:You just stick the tag out.
  439. Jake:But this solution to the server rendering problem is like, well, you are going to have to have.
  440. Jake:And in this case, it's not making it worse than Preact React.
  441. Jake:It's just kind of like something which is often touted as a benefit of web components is suddenly gone.
  442. Jake:So what is the point?
  443. Surma:Yeah, I guess like the point with custom elements was like, oh, all these like this machinery of like you automatically get attribute change callbacks of that is machinery in the browsers. You don't have to ship code to get that.
  444. Jake:Yes.
  445. Surma:But for server rendering, there is no HTML parser by default in node or something that can actually because you need to probably execute your custom element properly to figure out what is the server declarative shadow DOM code that needs to be in line so that yeah, that requires all this machinery and that like you say that that's the simplicity you've now lost it, you know, it's just another library that you need to do to stringify your web app so you can server render it.
  446. Jake:Yes.
  447. Jake:Yes.
  448. Jake:What we do at Shopify, because we are working on some web component stuff.
  449. Surma:Yeah.
  450. Jake:And what we do is we have our Shadow root defined using Preact.
  451. Jake:And we kind of made that decision just because it's a syntax familiar to a lot of the developers at Shopify because we use React sort of everywhere.
  452. Jake:But we're using Preact because it's smaller and we didn't need the complexity.
  453. Jake:Another reason for that choice was, you know, at some point, if we need it, we now have the ability in Node to render to string that Shadow root very easily because we won't need the DOM because we have a Preact definition of it all.
  454. Surma:Yes.
  455. Jake:And then we can just, you know, turn that into the contents of a template element if we need it.
  456. Jake:We haven't done that yet, but it's there.
  457. Jake:And so what is the point?
  458. Jake:And like I say, we're using it at Shopify.
  459. Jake:And the reason is, like, because you're building something which is real DOM, it will work in every framework that works with the DOM.
  460. Surma:That's pretty good.
  461. Jake:Yeah.
  462. Jake:So this is the idea.
  463. Jake:If you're using Vue.js, it's like, well, we can ship you a component that works in Vue.js.
  464. Jake:So if you're using Preact, well, we can just do the same thing.
  465. Jake:It works in Preact.
  466. Jake:The rough edge here is React 18 and below.
  467. Jake:They are just fixing it for 19.
  468. Jake:But a very small sort of wrapper component you can provide, which will generically make this stuff work in React as well.
  469. Jake:And I think this is where the benefit of Web Components is because it's so much better than what came before for creating components that don't care what they're running in.
  470. Surma:Yeah.
  471. Jake:Before, it was like jQuery UI or something like that, right, where you had to sort of put an element on the page somewhere and then another little bit of JavaScript, which you tell it, like, stick the date picker in here, please.
  472. Jake:And then it's all part of the light DOM.
  473. Jake:And you can end up, you know, especially if you're using a framework around it, you can end up sort of two systems fighting over the light DOM.
  474. Jake:So, yeah, I think that's one of the benefits.
  475. Jake:With Squoosh, we just for laughs, really, we made a couple of Web Components in there, like for pinch zoom and for the component which lets you sort of slide between the left-hand side image and the right-hand side image.
  476. Surma:Yes.
  477. Jake:We made those as Web Components.
  478. Jake:And it was actually pretty easy.
  479. Jake:And I have taken those components and used them in other projects.
  480. Jake:And it's like, well, this...
  481. Surma:Pinch zoom man the amount of times I've grabbed for it. It's so good.
  482. Jake:Right, and you didn't have to use Preact, even though, like, you know, Squoosh is built with Preact, but that component can be used anywhere.
  483. Surma:Yeah.
  484. Surma:Yeah.
  485. Surma:Yeah.
  486. Surma:Yeah.
  487. Surma:Yeah.
  488. Surma:have of touch and mouse and mouse wheel events and using scaling on the compositor all these things I knew it did right and it is I think very small, it's still an NPM to this day I think.
  489. Jake:Yeah, it is. Yeah.
  490. Jake:And so I think that's where, all of a sudden, the whole Web Components thing becomes worth it, is when you are targeting multiple, like, frameworks, which I don't, or no frameworks at all.
  491. Jake:I don't think many people are.
  492. Jake:And I think it was Adobe Photoshop for Web.
  493. Jake:Did they use Web Components?
  494. Surma:Salesforce Adobe also doesn't but I don't think it was Photoshop web because I think that's or is it I thought it was a lot of WebAssembly in there I don't know.
  495. Jake:Was that all those, like, maybe, like, Salesforce or some other teams, like, sort of building their sites with Web Components?
  496. Jake:Oh, definitely WebAssembly.
  497. Jake:I think, yeah, if I was building an app, I wouldn't be choosing Web Components.
  498. Jake:I might use components within the app, but only if I had that, if that portability was something that was mattering to me.
  499. Surma:Missel or misunderstanding I think by the time web components was used as a term React had already taken claim to the word components and associated with very specific expectations that web components do not meet and I think I would say they shouldn't.
  500. Jake:Which I can't decide if that's a failing of Web Components or not.
  501. Jake:It is a failing if you're saying Web Components are competing with React, which I think it always comes back to that that was a mis-sell.
  502. Surma:There needs to be something else like a another orchestration layer for those elements and because they're really just at their custom elements individual elements and not components at the orchestrate other components generically because that's just not a thing in HTML in general I feel like I feel like the select element is probably the most orchestrated element that we have in HTML maybe and if that's the pinnacle of high level component then yeah they can compete with.
  503. Jake:Yes, absolutely.
  504. Surma:React component which does like oh here's a whole carousel with tabs and a 3D animation a corner or something you know.
  505. Jake:And I think the thing that's holding us back there is HTML.
  506. Jake:You know, we talked about this in the putting React in the browser episode.
  507. Jake:But I don't know, the more I think about it, the more I think, like, if we want to get anywhere close to that, we need to come up with a format that takes all of the good bits of HTML, like the streaming and that, but gives us more than just strings as attribute values.
  508. Surma:Yeah and that's the thing right because people look at JSX and think oh it's the same but it works why can't it work on the web because well one of the big differences in JSX you are actually handling arbitrary values as property values and that makes a big difference.
  509. Jake:And maybe sort of demystifies some of the property attributes, things, I don't know.
  510. Jake:But it does feel like it's the HTML format that's holding us back for some of that.
  511. Jake:And no streaming because it's processed inside out, like it's kind of leaf first due to its sort of nature of, well, because it's literally JavaScript.
  512. Surma:Agreed.
  513. Jake:So it's like if you have a function which takes an argument, which is the result of a function, and you keep going deeper like that, it has to be handled leaf first.
  514. Jake:And it's your outer thing, which is called last because it has to find out what the attributes are by calling all of the inner functions.
  515. Jake:So that's kind of backwards to how HTML works.
  516. Jake:So yeah, that requirement means you hurt streaming.
  517. Jake:So yeah, JSX isn't the answer, but it has parts of the answer in there.
  518. Jake:Like it has the benefits in there that we want that HTML doesn't.
  519. Jake:But also, I think there's some quick wins as well.
  520. Surma:I feel like yeah this seems there's enough precedent on the web with like a for or template like reference another template tag by ID or something it doesn't seem like a wild leap to add this kind of function we have it with a label we have it with we even have it like SVG has it right like you can instantiate the same object with a link tag multiple times but it's referencing it by ID.
  521. Jake:I would love to see a version of declarative Shadow DOM that didn't need to be repeated for every element.
  522. Jake:Like you could just have sort of like one template tag.
  523. Surma:Yeah.
  524. Jake:Exactly.
  525. Jake:I think the complicating factor here is like if you have a template tag and you say, look, I want to be the initial shadow root for all my select elements.
  526. Jake:You have a case there where you have literal elements inside that template tag that are going to be represented multiple times throughout the page.
  527. Jake:So you would have to say like, are they cloned?
  528. Jake:Or is there some kind of crazier thing going on?
  529. Jake:You know, like, you know, is it something like SVG use?
  530. Jake:You know, I don't know.
  531. Jake:And who knows how that works?
  532. Jake:I don't know if that's...
  533. Surma:I would have just always assumed it's a clone of the template is just that as a template that needs to be instantiated.
  534. Jake:Right.
  535. Jake:And then if you go and modify that template using DOM, like what happens?
  536. Jake:It just, everything that was created prior to that doesn't pick up those changes, which I think is reasonable.
  537. Jake:I think that's reasonable.
  538. Surma:Yeah.
  539. Jake:I can imagine that conversation going badly at a spec meeting.
  540. Surma:At that point JavaScript is in play which means the elements have been registered and are active so if you have something that needs to be updated that should be part of the element code.
  541. Jake:That is fair.
  542. Jake:That is fair.
  543. Jake:Yeah, that's really it.
  544. Jake:It's not a happy tale, but I am enjoying using Web Components at Shopify for, you know, as we sort of work towards that payoff of being able to give people components and not require them to use a particular framework.
  545. Jake:But like, really, if that requirement wasn't there, I wouldn't be using them because it's just pure overhead other than that.
  546. Surma:Absolutely.
  547. Jake:So, yeah, I can see where people are coming from when they very strongly dislike Web Components, especially if they feel it's been sold to them as compared to React.
  548. Jake:I can see why they would feel that.
  549. Jake:But for that use case of like the jQuery UI, but today, like sharing components around, it's certainly the best we've got.
  550. Surma:I would agree with that.
  551. Jake:Shall we go away?
  552. Surma:Do we do the thing and we just end the podcast.
  553. Jake:Yeah, never speak to each other again until the next episode.
  554. Surma:Oh I did another just take a break for another year for no good reason that landed well I don't know.
  555. Jake:Oh, we could do that.
  556. Jake:That'd be nice, wouldn't it?
  557. Surma:Well we have our summer vacations I think covered with content now so that's good so we can come back with more click baity inflammatory podcast title where then the podcast itself is quite nuanced and actually not that interesting.
  558. Jake:Yes.
  559. Jake:Exactly.
  560. Jake:Well, that's how to do it today.
  561. Jake:It's all in the title.
  562. Jake:The title is the most important bit.
  563. Jake:Like, the rest of this is just, I mean, whatever.
  564. Jake:I mean, no one's listening at this point.
  565. Surma:Should we start doing like like shocked face thumbnails.
  566. Jake:Oh, God.
  567. Jake:You'll notice that they crept into the last few episodes of HTTP 203, like the shocked face thing and the titles, to be honest.
  568. Surma:The titles.
  569. Surma:You said 2 or 3 and I immediately thought OTMT because I saw.
  570. Jake:You've set up just an alias.
  571. Jake:Well done.
  572. Surma:Yes in my head it's all the same.
  573. Surma:It's my brand.
  574. Surma:Well I guess with this weird ending there's nothing left to say but happy next time.
  575. Jake:Happy next time.
  576. Surma:Bye.