Hacker News new | ask | show | jobs
by canvascritic 1023 days ago
I appreciate the author's attempt to contextualize web components, but I have a few bones to pick, having seen web components used to a pathological extent in various projects

First, the idea that one of web components' strengths is bypassing serverside rendering is a bit misleading. SSR has been foundational to reducing time to first meaningful paint, ensuring accessibility, and improving seo. to argue that bypassing it is an advantage seems antithetical to best practices, even when using client-side tech like web components.

Second, the transition example from react to svelte highlights the use of web components as a bridge, but I fear it oversimplifies the reality of such transitions. Its true that web components might provide a superficial level of interoperability, underneath, the application architecture, state management, and data flow can differ vastly between frameworks. Simply plopping an old component with a new one doesn’t mean they’ll play nice without substantial architectural considerations.

Finally, the mention of "no bundler, no transpiler" as an advantage is curious. in practice, the modern web development ecosystem has moved towards using tools like bundlers and transpilers to optimize delivery, reduce overhead, and facilitate modular development. this isn't about complexity, but rather about efficiency and best practices.

Web components certainly have their place and, used judiciously, can certainly add value. It's just essential to approach them with a nuanced understanding and not as a silver bullet.

3 comments

> First, the idea that one of web components' strengths is bypassing serverside rendering is a bit misleading. SSR has been foundational to reducing time to first meaningful paint, ensuring accessibility, and improving seo. to argue that bypassing it is an advantage seems antithetical to best practices, even when using client-side tech like web components.

This comment deserves some clarity.

Web components should not bypass server-side rendering. However, that server-side rendering should not come from the web components themselves. Rather, the "SSR" in this case should be the job of whatever generates the page HTML.

The page HTML should include default "slotted" content (inside the custom element's tag) to be picked up by the web component when the page loads. That's the best way to do progressive enhancement in web component land. Whenever I reach a point when I think, "Gee, I wish I could SSR this web component," I take it as a bad smell, like I'm probably not taking advantage of web component features.

Put another way, I wouldn't want to SSR a web component for the same reason I wouldn't want to SSR a <p> tag. The latter makes no sense, right? Web components are custom elements, and they should be treated like elements, and designed like elements.

> Web components certainly have their place and, used judiciously, can certainly add value. It's just essential to approach them with a nuanced understanding and not as a silver bullet.

Fully agreed with this, it should be repeated over and over. Web components can be part of a balanced diet but they can't be the whole meal.

If I understood you correctly, then we’re exactly on the same page. That is, web components being a standalone thing that you render “as is” on the server. Their point is to extend interaction on the client and not to be a templating language on the server.

The author mentioned Lit not having a stable SSR story (a small, fast library to leverage web components).

My suspicion here is that some do too much within their components that they want to render on the server.

There’s two possible solutions already:

1. Don’t generate all your html inside the component (in js), but instead use the component to enclose markup that you render on the server.

2. Decouple html rendering (lit-html) from your component. If your component calls a function that spits out html, so can your server (if it runs JS).

- Server side rendering is essentially a hack to work around web crawlers' inability to parse dynamic single page apps... My first issue with this is that it doesn't make sense to me why someone would build a high-exposure public website/landing page as a dynamic single page web app, what you really need is a website; these are much more lightweight, easier to cache and deliver over CDN and they use up far fewer resources (no need to serve libraries which are not necessary for the current page). Also, why would you want web crawlers to parse a dynamic application (e.g. dashboard and private areas)? It shouldn't even be visible unless the user is authenticated (which the crawler is not!). What should you show the web crawler in that case? Do you really need Google to see all your apps' form templates with all the empty input fields? SEO is for marketing; in this case, you need a website with a landing page and potentially a blog, not a dynamic single page app.

- About bundling, the current reality is that frameworks like React come with a huge amount of dependencies/boat... On the other hand, native Web Components require no dependencies. Web Components will generally load much faster even without bundling than React + all dependencies in a bundle because those bundles are often huge... Not to mention that nowadays, tags expose some nice attribute which let you control the loading and execution order of scripts in a highly fine-grained way (e.g. async and defer attributes on the script tag). That's even without going into the fact that since HTTP2, servers have the ability to preemptively push resources to the client without any round-trip latency. Also, loading resources separately allows for more fine-grained cashing with CDNs; you share some components between some pages and you only need to load what you need explicitly as needed.

SSR feels like it was a term coined by marketers more than it does engineers.

Every time I hear someone describe their reasons for using SSR I usually can't figure out why they're building an SPA in the first place.

> SSR feels like it was a term coined by marketers more than it does engineers.

What I see is that sometimes young front-end developers use their favorite tools (ie. the JS ecosystem) and are unaware of (or have not practiced) the "old way" of building server-side applications and websites.

There's definitely some truth to that, but I also see a lot of older developers who are equally unaware of the newer ways of developing, and then struggle to see the potential improvements there.

For example, front-end templating systems are usually come with a lot more than more traditional templating engines. I can get autocomplete on component names and attributes, squigglies when I do something wrong, type safety, as well as more logical import/scoping rules - just follow the import lines and you find where a component was defined. Meanwhile, partials tend to be much more stringly typed, have very little IDE support, and often still seem to use a global partials folder to define reusable components.

The other big thing that I miss in traditional templating engines is scoping for web technologies. Being able to collocate styles and HTML structure is incredibly useful, and makes it a lot easier to share components around in different contexts. Similarly, if I have an accordion partial that uses a bit of Javascript for progressive enhancement, it's very useful to be able to group that Javascript with the partial, scope it to that context, and let the templating engine hook everything up. Scoped CSS (however you implement it, be that CSS modules, CSS-in-JS, tailwind, or whatever else) is a godsend for making really robust components, and I've never found anything even half as good on the server side.

> There's definitely some truth to that, but I also see a lot of older developers who are equally unaware of the newer ways of developing, and then struggle to see the potential improvements there.

Hey, we were just waiting for the dust to settle, we're catching up now ;)

It's not clear to me what you're describing is a "newer way of developing". Type safety and IDE autocompletion are nothing new - these are decades old concepts that are finally making their way to dynamic languages like javascript. Scoped CSS/JS isn't a unique concept to SPA's, you can absolutely implement the same thing in a page loading app.
Type safety in templating is almost unheard of though, alongside autocomplete for things like template arguments. For example, in JSX, if I write <Header [CTRL+SPACE], I immediately get a list of all the keyword arguments I could pass to that component, plus documentation, types etc, just like I'd get if I'd been calling a function in, say, Java. And if I pass the wrong arguments, I'll get errors at compile time or in my IDE.

I know there are a handful of tools that can do this for server rendered templates, but they are very rare and very underutilised, and typically don't have the LSP/IDE support that JSX or single-file-components do.

I do not know any server-side templating languages that do scoped CSS, much less any sort of scoped JS. By that I mean, I can write a CSS declaration (in CSS syntax or otherwise) and guarantee that it will only be used in one place, scoped to a single component (or template partial). This means I'm no longer stuck with the global CSS namespace, and I can link my CSS files directly with the components that use them.

> Server side rendering is essentially a hack to work around web crawlers' inability to parse dynamic single page apps... My first issue with this is that it doesn't make sense to me why someone would build a high-exposure public website/landing page as a dynamic single page web app, what you really need is a website

Even when building a website, it is exceedingly convenient to compartmentalize large chunks of code into small, manageable UI components that can then be composed together. You will remember the uniquitous "partials" in server-side templating languages/engines/frameworks, such as rails, blade, or nunjucks. Such partials are good for extracting markup; but they do not solve the problem of co-locating the markup with the styles and interactivity associated with it. You can see an attempt to achieve this vision in such projects as Enhance, or webc, or even Astro, whose focus is on building html-first, server-rendered "websites" out of small UI components. But the syntax that these projects use is non-standard and unique to each of the projects. We are in dire need of a web standard way of doing sane server-side templating, which web components could have helped achieve; and my hope is that they will; only right now they still suck at this.

> Even when building a website, it is exceedingly convenient to compartmentalize large chunks of code into small, manageable UI components that can then be composed together.

React was designed by Facebook, a website that is mostly behind a login wall and not indexed. The complaint that React is bad for SEO is therefore somewhat ahistorical. Of course you can use React as a templating engine with SSR and it works just fine, but the original value proposition of React was interactivity.

It seems that nowadays the majority of people are using React in non-interactive contexts, which can be a bit weird for those of us who adopted it as a replacement for jQuery, rather than as a replacement for template engines.

I did not even mention React in my comment :-) React isn't web components. React didn't even invent the idea of a ui component. I agree that Facebook created React for large interactive web sites; and I know that as a server-side templating engine, React is very slow compared to competition; which is why I desperately want web components to succeed on the server and to stardardize ergonomic component-based templating.
> what you really need a website

finally some sanity

To me this seems to be the root of all problems with SPAs. They are mis-used for websites, and so a ton of technology has been built to make them work like those. Nobody cares about SEO in Figma, or your blog's web editor. We wanted to have a single hammer for everything and now the hammer has three handles.
Agreed, and one of the nice things about Web Components is that it makes it practical to build dynamic components for use on multi-page websites since the bandwidth overhead for including a component into a page is so small (since most of the logic is built into the browser). No need to include an entire framework bundle just to include a small component. For example, I built a dynamic navbar as a Web Component and I just included that component on multiple pages (great for code re-use). All pages loaded instantly. I could never do that with a framework.

I'd never considered to implement a multi-page website navbar as a front-end component before. For code reuse in a multi-page website, one would typically rely on a server-side pre-processing engine (e.g. PHP, ASP.net, ...) but the pervasiveness and lightweight nature of web-components now makes this a possibility.

> All pages loaded instantly. I could never do that with a framework.

Of course you could. Depends on framework, but you certainly could.

I like the typo “cashing”!

It’s like we’re “cashing” in on REST being inherently cache friendly.

@canvascritic great points. What would you say where web components are good at?