[HN Gopher] Isomorphic Web Components
___________________________________________________________________
Isomorphic Web Components
Author : Fudgel
Score : 58 points
Date : 2024-12-14 07:19 UTC (1 days ago)
(HTM) web link (jakelazaroff.com)
(TXT) w3m dump (jakelazaroff.com)
| Etheryte wrote:
| I don't really think server-side rendering is an important reason
| why most people don't use web components. Most web applications
| that use components of any sort are largely SPAs of some variety
| and don't care one bit about server-side rendering. In my
| opinion, the main reason web components aren't widely used is
| that the alternatives are just better. I'm yet to see a strong
| case being made where web components are favorable for a reason
| other than purism.
| afavour wrote:
| From my personal experience the lack of SSR is one reason I
| don't use web components. But that said there isn't a
| particularly persuasive case to use them either, other than it
| being nice to use standards.
| pier25 wrote:
| > _Most web applications that use components of any sort are
| largely SPAs_
|
| How did you get to that conclusion? Honestly asking because my
| hunch is that it would be the opposite.
|
| > _I 'm yet to see a strong case being made where web
| components are favorable for a reason other than purism._
|
| IMO it's wrong to see web components as a universal solution to
| all client-side use cases.
|
| Web components are amazing for distributing widgets to third
| party users. From users authoring HTML in any number of
| environments to a way to plug modern JS stuff into SSR backend
| frameworks.
|
| Back in 2016 I worked in library of widgets for interactive
| education ebooks. People producing the ebooks could barely
| write HTML so being able to add interactivity with configurable
| custom tags was extremely easy for them. Currently I'm working
| in an embeddable and customizable audio player with web
| components. Typically you'd use iframes which are quite heavy
| and have serious limitations. In both use cases, web components
| were the right choice.
| DrFell wrote:
| Websites built with JavaScript frameworks need SSR because of
| SEO. Applications don't, so most are SPAs, because they can
| be. The fully decoupled SPA is a special architecture.
| Complexity isn't just lessened, a lot of it vanishes. Poof,
| bye bye headaches. If you can use it, you do, and most web
| applications can, so they do.
| ww520 wrote:
| I'm curious to see a plus and minus comparison of web component
| vs other techs (I assume those are React, Vue, etc.)
| deergomoo wrote:
| I read a lot of blog posts from both sides in the most recent
| big "web components vs frameworks" brouhaha a month or so ago.
| The conclusion I came to was that both sides' arguments were
| mostly correct but orthogonal to each other, so neither side is
| ever going to convince the other because they're not _really_
| seeking the same goal.
|
| The pro-web-component folks argue that WCs are standardised and
| will continue to work basically indefinitely regardless of the
| ebbs and flows of popular libraries, and because it's easier to
| progressively enhance and therefore more accessible. This is
| correct, and those points are valuable if what you seek is a
| way to add resilient islands of interactivity to your document.
|
| The pro-framework folks argue that in their model where the
| entire UI is a function of state, WCs are incredibly
| cumbersome, because all you really want from a component is to
| be a smaller function with which you can compose part of the
| whole. They are not nearly as concerned with maintaining that
| component under React vX in five year's time, because _the
| entire system_ is written in React vX. The components are not
| maintained or used as individual units unless you are shipping
| a library. This is also correct, and those points are valuable
| if what you seek is an effective way to break down complexity
| in your application UI.
|
| Of course, many (maybe even most?) SPAs _should_ be documents
| with progressive interactivity--it involves less fighting with
| the fundamentals of the web (which is, ultimately, still based
| around documents) and therefore offers better performance and
| accessibility with less effort. SSR for frameworks is an
| absurdly complex solution to a problem that doesn 't exist if
| you can just send a complete document right to the browser.
|
| But, likewise, implementing a genuine high-interactivity web
| application using web components would be far more difficult
| than using a framework, and I am certain would result in re-
| implementing some sort of reactive UI/function-of-state
| paradigm anyway.
|
| Personally I think it's kind of a pointless debate, until and
| unless we get something that is close enough to <insert popular
| JS framework here> + SSR built into the browser. I don't know
| how that would work or whether it's even possible, but at that
| point the set of standards would actually cover all of the
| problems everyone is trying to solve and it would be worth
| arguing whether or not to use them.
| solardev wrote:
| Exactly. Good breakdown.
| WA wrote:
| > SSR for frameworks is an absurdly complex solution to a
| problem that doesn't exist if you can just send a complete
| document right to the browser.
|
| So, React is just a view library. It's made to map state to
| DOM changes. Except it's not just a view library, because if
| you write an app with React, you are writing a React app. You
| slice and dice your view up and put them into React
| components. Now, since you want to use your React components
| on the server and not slice and dice them up again in another
| view library, you morph that DOM-manipulating lib into a
| templating engine that generates static HTML. Except you call
| it "server side rendering", because "templating engine"
| sounds so 2010 and "static site generation" is also not the
| right term, because the output isn't a static HTML page, but
| can change with every page request. Of course, the "React"
| part of React is completely ditched in SSR, because you don't
| need to continuously modify the DOM based on your state.
| React on the server is what PHP templates have been doing
| forever. Outputting HTML in PHP is "view = f(state)". We've
| come full circle.
|
| I sometimes wonder if younger web devs even understand that
| SSR isn't, like, really rendering a page on the server, but
| basically means "we produce frickin HTML like we've been for
| the last 30 years, except our tools are now 10x as complex to
| such a point that we don't understand them anymore", because
| 90% of our view library does nothing on the server, because,
| you know, there is no DOM. There is only HTML as a string
| send over HTTP.
|
| Having said that: Your analysis is completely correct. The
| discussion really is orthogonal and I'm not sure I see the
| point in rendering web components on the server, since most
| web components benefit from interactivity through JS. If I
| merely encapsulate a bunch of HTML tags, I can ditch the
| custom element entirely and send the HTML tags down the wire
| by themselves.
| MrJohz wrote:
| I think when trying to understand SSR, it's worth
| remembering what actually was happening with older systems
| like PHP. You say that outputting HTML in PHP is `view =
| f(state)`, and this is to a certain extent true, but it
| meant that anything on the client side was then `view =
| f_client(state_client, f_server(state_server))`, and
| getting applications to remain sane with anything more than
| the bare minimum of interactivity was painful. I remember
| this era, and debugging constant state issues was very much
| the reason that we ended to moving towards client-side web
| frameworks: you only have to worry about one `f` and
| (mostly) one `state`.
|
| In my experience, most of the people exploring SSR are very
| acutely aware of that era, both the benefits and the
| negatives, and are trying to build systems that allow
| developers to retain a consistent overall view function
| without having to maintain that across multiple codebases
| in multiple languages. That doesn't just mean rendering
| HTML, but also ensuring that the frontend and backend agree
| on how to update that HTML if the state ever changes, or
| ensuring that progressive enhancement is possible while not
| requiring the entire site to reload every time I update a
| form field.
|
| Now I think there's a good argument to be made that many
| applications don't need this additional complexity - they
| can continue to be rendered entirely server-side, or
| entirely client-side, and not need to share state at all.
| But if you do need state to exist in both the server and
| the client, modern SSR frameworks are typically a pretty
| good approach.
| nosefurhairdo wrote:
| > WCs are standardised and will continue to work basically
| indefinitely regardless of the ebbs and flows of popular
| libraries
|
| Help me understand; is this suggesting that older
| frameworks/libraries are expected to stop working at some
| point? I'm shipping 10+ year old libraries in production
| without incident. Really don't understand the "resilience"
| argument for WCs.
| pegasus wrote:
| 10+ years is nothing compared with a human lifespan. Web
| standards are more likely to still be around in 50 years
| than react vX.
| teg4n_ wrote:
| react uses those same web standards. It will not stop
| working either. You may not be able to upgrade to the
| latest React version assuming there are breaking changes,
| but the same can be said for the various frameworks
| people use to create web components.
| MrJohz wrote:
| > The pro-web-component folks argue that WCs are standardised
| and will continue to work basically indefinitely regardless
| of the ebbs and flows of popular libraries, and because it's
| easier to progressively enhance and therefore more
| accessible. This is correct, and those points are valuable if
| what you seek is a way to add resilient islands of
| interactivity to your document.
|
| I'm not sure that's even that correct. If you write code
| using browser APIs that are currently standardised, your code
| will work indefinitely, whether or not you use Web
| Components, React, or jQuery. Hell, we used to have jQuery-
| based components with the whole $(...).datepicker() system.
| Yes, it has its flaws, but it'll still work today if that's
| what your want from it.
|
| Secondly, I don't think Web Components do work well from a
| progressive enhancement perspective. Progressive enhancement
| is starting from the bare minimum (i.e. just HTML and some
| styles, if that), and progressively adding features to that
| initial state that don't prevent any of the previously-added
| features from working. So you start with an HTML form
| skeleton, and you add some validation attributes, you add an
| event handler that calls fetch instead of reloading the page,
| you extend the address input so that it suggests real
| addresses - but the whole time, the HTML form is still there
| and it still works.
|
| But without Javascript, Web Components are essentially empty
| holes that can't do anything. They don't progressively
| enhance anything. You can to a certain extent wrap existing
| elements, you can take the isomorphic approach described in
| this post, etc. But even when you do that, the browser will
| replace the contents of the element with the component's
| rendered output when the Javascript comes online, potentially
| deleting any user inputs if they'd interacted with the
| previous context. If your aim is true progressive
| enhancement, you should probably look in a different
| direction.
|
| In fairness, I don't disagree that these claims are often
| made by Web Component proponents. But I think they're the
| wrong claims to be making. Web Components seem to be most
| useful if you're trying to isolate a complex stateful
| component written by one person or team and ended it into a
| complex stressful application written by a different person
| or team. They're essentially like lightweight iframes. This
| is really useful, and should be promoted more - but it's also
| quite a specific use.
| throwitaway1123 wrote:
| > I'm not sure that's even that correct. If you write code
| using browser APIs that are currently standardised, your
| code will work indefinitely, whether or not you use Web
| Components, React, or jQuery.
|
| The most charitable interpretation of this argument is that
| framework specific component libraries assume for the most
| part that you're using that specific framework. The
| documentation for popular React component libraries like
| shadcn are largely incomprehensible if you're not using
| React. Libraries like Shoelace (now being renamed to Web
| Awesome) make no such assumptions. You can just drop a
| script tag into your page's markup and get started without
| having to care about (or even be aware of) the fact that
| Shoelace uses Lit internally.
|
| > But without Javascript, Web Components are essentially
| empty holes that can't do anything. They don't
| progressively enhance anything.
|
| This is not true if you're using the new Declarative Shadow
| DOM API [1]. You literally just add a template tag with a
| shadowroot mode attribute inside your custom element, and
| then the component works without JavaScript. When (or if)
| the JavaScript loads, you simply check for the existence of
| a server-rendered shadow root using `internals.shadowRoot`.
| If a shadow root already exists then you don't have to
| replace anything, and you can attach your event listeners
| to the pre-existing shadow root (i.e. component hydration).
|
| [1] https://web.dev/articles/declarative-shadow-
| dom#component_hy...
| egeozcan wrote:
| Here's one case that I think is strong: At work some teams use
| JSF, some use React. We need to deliver components to both. We
| chose lit and we're very happy.
| potsandpans wrote:
| Only partially related to the blog post, but...
|
| The thing that is lost on me with all of these webcomponents
| solutions is that they inevitably rely on tagged templates to do
| the heaviest lifting.
|
| I don't want to write strings, I want to write statically
| analyzable code. IDEs do some heavy lifting here for visual
| hints, and there are a few html-in-js linting solutions, but none
| of them are very compelling.
| Onavo wrote:
| Well since the letter x is taken, we can use w for web
| components. So a component file with tagged HTMl strings should
| have the extension .tsw or .jsw
| madeofpalk wrote:
| This too was my roadblock in the article
|
| > You'd be forgiven for thinking you were looking at a React
| component! Frankly, I don't see a fundamental difference
| between these and frameworks like Svelte or Vue
|
| Regardless of whether you should be forgiven for thinking it's
| a react component, it omits it's biggest strength - JSX is just
| JavaScript function calls, and thus can be composed as
| JavaScript and type checked as java/typescript.
|
| This to me is the fundamental difference between React/JSX and
| other approaches. Any framework that gives up on type checking
| for the view layer is a non-starter in my books.
| CharlieDigital wrote:
| The fundamental differences are quite stark.
|
| Vue, Svelte, web components, and vanilla only execute code
| that is marked as a callback.
|
| Example: let x = 0 var counter =
| computed(() => ... )
|
| In this Vue snippet of an SFC, the callback in the computed
| executes in reaction to some change without invoking the
| assignment of x (obviously a trivial case here).
|
| DOM + JavaScript is the same
|
| React invokes the entire component function and all calls and
| allocations in the path of the component function. The mental
| model is inverted in a sense.
|
| This is one of the reasons React generally performs more
| poorly in both speed and space.
| spankalee wrote:
| Static analysis works on strings: source code. Similarly, it
| can, and does work on the strings in a tagged template literal.
|
| Lit's templates are HTML with bindings. They're very
| analyzable, including checking for valid structure, associating
| tags with definitions, type-checking bindings. The tools that
| do this parse template strings, build an AST, and run analysis
| passes just like other source analysis tools.
|
| Developers get standard intellisense features like jump-to-
| definition, hover-over docs, errors on invalid properties and
| events, etc.
|
| But also... templating is an _implementation_ concern.
|
| To build a web component you don't have to use a tagged-
| template-based system. There are template systems that use JSX.
| You can use Preact, or React themselves. And your component
| users don't ever have to know what template system you chose to
| implement your component.
| sirwhinesalot wrote:
| Great stuff, but if you are writing your own components just
| stick to light DOM and do not write code to generate DOM elements
| for the component to look right.
|
| Let's say you are making a splitter component. Do not do this:
| <my-splitter> <div slot="left"> <my-handle
| slot="handle"> <div slot="right"> </my-splitter>
|
| With some divs on the inside assigned to slots. Instead do this:
| <my-splitter> <div data-slot="left"> <my-handle
| data-slot="handle"> <div data-slot="right"> </my-
| splitter>
|
| Looks almost the same right? Except the one at the bottom is
| trivially server-side rendered. *It already is*.
|
| Stay on the light side.
| egeozcan wrote:
| Lit has an experimental SSR plugin:
|
| https://lit.dev/docs/ssr/overview/
|
| I also sort of made SSR work under next.js (not to be mixed with
| server-components), but that took a lot of hacks and going off
| the beaten path:
|
| https://www.npmjs.com/package/@lit-labs/nextjs
| finiteparadox wrote:
| Why do they have to call it "isomorphic"? that already has a
| meaning that doesn't really coincide with how web dev people use
| it..
___________________________________________________________________
(page generated 2024-12-15 23:00 UTC)