[HN Gopher] Hydration is pure overhead
       ___________________________________________________________________
        
       Hydration is pure overhead
        
       Author : steve8708
       Score  : 58 points
       Date   : 2022-04-20 18:50 UTC (4 hours ago)
        
 (HTM) web link (www.builder.io)
 (TXT) w3m dump (www.builder.io)
        
       | ushakov wrote:
       | if none of this makes sense to you - don't try to make sense of
       | it or you'll be disappointed
       | 
       | do you need 2000+ of dependencies to essentially show a HTML page
       | in a web browser?
       | 
       | why should you have to wait 5 minutes to generate a static
       | website?
       | 
       | Netlify and Vercel are well aware of these inefficiencies and
       | offer you a "cloud" solution that promises to solve the problems
       | you shouldn't even have had in the first place
       | 
       | if you think you _need_ things like Gatsby or Next.js you've been
       | brainwashed by capitalists
        
         | chrischen wrote:
         | You don't need dependencies like webpack, react, or even any
         | javascript at all to show static pages... and it would be a
         | poor use of them just to write static html. But if you want
         | interactive elements like image editors, rich text edition,
         | fancy tables, then you start needing smarter and smarter build
         | tools to bundle it all together and support the maintenance of
         | interactive complex web applications.
         | 
         | I'd also argue that having a static build tool that generates
         | HTML will also allow you to write more HTML and more complex
         | HTML, as you can abstract away reusable components. So there
         | are benefits even if you are serving non-interactive HTML
         | pages. Just cache the React build output.
        
           | ushakov wrote:
           | why do i need React for any of this?
           | 
           | most template engines have partials and some have macros
           | (Jinja2)
           | 
           | React-based static site generators are so slow that they're
           | unusable for any website that has more than a couple pages
        
             | chrischen wrote:
             | I don't use React-based static site generators, but I'd
             | imagine if they become slow it's because it's generating a
             | large code-base, but unless you provide some benchmarks
             | showing compilation of React vs some other templating
             | system I can't really take your argument against it for
             | this use case.
        
               | ushakov wrote:
               | don't take my word for it
               | 
               | https://css-tricks.com/comparing-static-site-generator-
               | build...
               | 
               | Next.js and Gatsby are the slowest
        
             | ratorx wrote:
             | The developer experience is better. I personally like type
             | safe templates, and just the JSX bits of React are one of
             | the most mature type safe templating frameworks with very
             | good editor support.
        
         | matthoiland wrote:
         | I've been brainwashed by consumers - they demand and expect a
         | certain experience on the modern web. Also, you can run Next.js
         | on a Raspberry Pi and free Cloudflare DNS+SSL. :shrug:
        
           | ushakov wrote:
           | what are their demands?
           | 
           | pretty sure my Raspberry Pi will just give up after pulling
           | 2000 npm packages and building native modules
        
             | oblak wrote:
             | You're wrong. I used to run node + mongo on my 3B+ until it
             | died on me one last time :(
             | 
             | It could manage much, much more than that. Now, I haven't
             | tried running Next on it but unless it's worse than Nuxt
             | (which isn't all that fast, really), it should be fine.
             | 
             | These little SBCs are only lacking at GPU tasks
        
               | ushakov wrote:
               | have you tried using a compiled language and a database
               | that isn't web-scale?
               | 
               | this should fix your dead board /s
        
               | oblak wrote:
               | No, I am not manly enough :(
               | 
               | Pretty sad about it dying on me, though. This time it
               | wasn't just a borked flash card.
               | 
               | Been waiting for a 5 but it's taking ages
        
           | dham wrote:
           | The fallacy of our generation. Except they literally don't.
           | They just don't want their computer to not run out of battery
           | loading your resume driven developed site.
        
       | wonnage wrote:
       | This article complains that downloading stuff is slow and then
       | goes on to propose a solution where you have to wait for stuff to
       | download before firing a scroll handler.
        
       | legym wrote:
       | The company I work for is making a big deal about client-side
       | hydration. We use nextjs for our sites. My director was asking
       | about Svelte.
       | 
       | "Something i wanted to mention is both the React team and nextjs
       | team are aware of this and are working on a solution to address
       | needing to load Javascript on the client. Its called React Server
       | Components
       | 
       | React Server Components Documentation
       | https://reactjs.org/blog/2020/12/21/data-fetching-with-react...
       | 
       | Nextjs Blog on Server Components
       | https://vercel.com/blog/everything-about-react-server-compon...
       | 
       | Nextjs Documentation on Server Components (Alpha)
       | https://nextjs.org/docs/advanced-features/react-18/server-co...
       | 
       | We can try it out today on a platform that supports a node
       | environment. This is from nextjs docs. I have a few thoughts on
       | Svelte, but just wanted to point this out!"
       | 
       | With Server Components, there's zero client-side JavaScript
       | needed, making page rendering faster.
        
         | ushakov wrote:
         | > React Server Components
         | 
         | really?
         | 
         | c'mon could we please ask the React folks to stop making simple
         | things hard?
        
         | grayrest wrote:
         | If you're into this sort of thing you should look into Marko.
         | They're kind of obsessed about page load perf with the
         | justification that it's good for e-commerce. They've also been
         | into streaming, partial hydration, out of order rendering, etc
         | for years as part of that general effort.
        
       | recursivedoubts wrote:
       | Sometimes you just have to laugh.
       | 
       | We've been doing SSR all along, folks: server side templates.
       | 
       | Yeah, HTML was pretty hamstrung as a hypermedia, which made for
       | mediocre UX, but that's been fixed by libraries like unpoly,
       | hotwire, or, my own, htmx.
        
         | daenney wrote:
         | htmx is the first thing that's made me feel like I can build a
         | useful front end again in years. Plain server side rendering of
         | templates and a bit of sprinkles on top. It's awesome and thank
         | you!
        
         | ushakov wrote:
         | the reason we need all this is so that Netlify and Vercel can
         | make money
         | 
         | there's no other explanation
         | 
         | it's a capitalist game and if you want to stay sane, you
         | shouldn't play it
        
           | hunterb123 wrote:
           | > there's no other explanation
           | 
           | Faster initial load times for PWAs?
           | 
           | No conspiracy theory or capitalism rant needed.
        
             | briantakita wrote:
             | Isomorphic (the same js libraries on the server & client)
             | software is also nice. With WASM, it is possible with other
             | programming languages, though js/ts has a large head start
             | in the isomorphic web space.
        
             | ushakov wrote:
             | faster load times is achieved by _not_ using javascript,
             | (pre-) rendering content on server and caching with CDN
             | 
             | this is how Wikipedia does it for the last 20(?) years and
             | they sure won't be changing that any time soon
             | 
             | PWA is a whole different topic
        
               | hunterb123 wrote:
               | > PWA is a whole different topic
               | 
               | No it's not, as hydration is used to improve the initial
               | load times for PWAs. Afterwards PWAs will load offline
               | first.
               | 
               | > faster load times is achieved by not using javascript,
               | (pre-) rendering content on server and caching with CDN
               | 
               | Yes you can make sites not using JS and should in certain
               | scenarios, that's not relevant here.
               | 
               | > this is how Wikipedia does it for the last 20(?) years
               | and they sure won't be changing that any time soon
               | 
               | Wikipedia is a web site, not a web app. It works really
               | well as a site and thus uses technologies meant for web
               | sites.
        
               | ushakov wrote:
               | > hydration is used to improve the initial load times for
               | PWAs
               | 
               | this very sentence sounds absurd
               | 
               | how many websites out there need to work offline?
        
               | hunterb123 wrote:
               | You didn't address my last points but I'll still address
               | this comment.
               | 
               | > this very sentence sounds absurd
               | 
               | Which part? "hydration", "improve the initial load
               | times", or "PWAs"?
               | 
               | Let me rephrase if you are confused. It renders a
               | snapshot of the app on the server so when you first load
               | the web app it's rendered already. Then the client picks
               | it up from there. It's completely optional to do this.
               | 
               | > how many websites out there need to work offline?
               | 
               | Are you asking if it's useful to have access to
               | information and entertainment offline? For me the answer
               | is yes.
               | 
               | It depends what you are making, but yes I think you
               | should strive to make things work offline if you can.
               | 
               | Also websites can work offline without CSR. That's not
               | really what this is about.
               | 
               | Hydration is about improving initial load times of CSR. I
               | really don't know how to simplify this further.
        
         | eyelidlessness wrote:
         | Is this condescension really necessary? I don't think it helps
         | the discussion generally, but particularly from authors of
         | libraries in a similar space with a different approach. Lots of
         | others in the space, many whose work would likely get a similar
         | reaction, are quite welcoming to competing approaches and even
         | speak highly of them.
         | 
         | That said, I think you might want to consider looking more
         | closely at how Qwik works. It produces markup metadata that's
         | not dissimilar to what I see in htmx. I don't know if it's a
         | direct inspiration, but that similarity seems particularly odd
         | to dismiss so bluntly.
         | 
         | The major philosophical difference between the two is the
         | authoring experience: Qwik annotates the HTML with a compiler,
         | in htmx it appears the expectation is you write the annotations
         | directly. Qwik's server side templates just happen to be
         | authored as JSX components. Both are completely valid! Probably
         | more a matter of preference than anything.
         | 
         | Personally, I prefer the Qwik approach. But I welcome yours as
         | well and encourage people who would prefer it to choose it.
         | Both are significantly better, in many cases, for users than
         | the current outcomes from many other frameworks which appeal to
         | the devs Qwik is targeting. Isn't that also welcome given the
         | state of web dev today?
        
           | recursivedoubts wrote:
           | that's fair, I was being too sardonic
           | 
           | i've spent a bit of time today looking into qwik and I
           | appreciate what they are trying to do
           | 
           | not my bag, but i'm obviously a contrarian in the web world
        
             | eyelidlessness wrote:
             | Hey, thank you for this response though! It's much more
             | what I like/hope to see in the ecosystem. Also I'm an old
             | curmudgeon so I relate, and sometimes need a nudge to turn
             | the contrarian knob down to friendly :)
        
         | hunterb123 wrote:
         | This is for enhancing CSR initial load times. For apps that
         | need to work offline, have a lot of UI state, have sister
         | native apps, etc.
         | 
         | Yes we've had SSR, noone is disputing that, nor is it relevant.
         | These are separate solutions for separate problems.
         | 
         | I agree some people reach for the wrong tools sometimes, but
         | that's a universal problem.
        
           | lf-non wrote:
           | Not that irrelevant.
           | 
           | Traditional SSR involved a separation between templates which
           | contain presentation logic, and controllers for mediating
           | business logic, persistence etc.
           | 
           | If your backend & frontend are in same language, or you use
           | template engines with implementations in mutliple language
           | like handlebars/pug/soy etc. you could easily render the same
           | templates using JS and your client side can have as much ui
           | state, interactivity etc. as you want.
           | 
           | If we adopt incremental enhancement then the fetching of
           | templates can be delayed - we primarily need the controllers
           | which handle dom events to make the server-rendered ui
           | interactive. This is easily achievable through libraries like
           | stimulus where controllers can add complex interactivity to
           | server rendered templates and re-render them if needed
           | through templates which are fetched on demand. We can even
           | preserve form element states by using libraries like morphdom
           | for swapping content.
           | 
           | However, what really breaks down all of the above is the
           | concept of components as popularized by React etc. When we
           | start writing react-style components then our rendering logic
           | and associated behavior are tightly coupled and we need to
           | pull in all the rendering logic for enhancing the server
           | rendered content. React devs like to preach that traditional
           | separation of concerns is not useful in practice and it is
           | better to have rendering code colocated with behavior - but
           | solutions like this just demonstrate that this separation did
           | actually have some merit albeit at the cost of some
           | indirection.
           | 
           | What solutions like Qwik are attempting to do is enabling
           | folks to keep writing component oriented code but now we need
           | a fancy compiler tooling that deeply integrates with the
           | stack. The approach does have its merits but it is just one
           | path to address the problem.
        
         | cultofmetatron wrote:
         | don't forget LiveView!
        
       | yboris wrote:
       | For reference, Misko Hevery, the author of this post, is the
       | creator of _Angular_.
       | 
       | At the end of the article, there's his solution:
       | https://qwik.builder.io/guide/overview
       | 
       | > Qwik is a new kind of web framework that can deliver instant
       | loading web applications at any size or complexity. Your sites
       | and apps can boot with less than 1kb of JS
        
         | wwweston wrote:
         | > is the creator of Angular.
         | 
         | Welp, that's reason enough for me to ignore him entirely.
         | Especially on the topic of "overhead."
         | 
         | Angular was an inexcusable atrocity.
        
           | fleddr wrote:
           | That's a terrible mindset no matter how much you hate
           | Angular.
        
       | CreepGin wrote:
       | While we are on the topic of browser event handlers and
       | "embracing how browser actually work", I can't help but mention
       | that the builder.io website's top navbar cannot handle ctrl +
       | clicking (for opening links in a new tab).
       | 
       | It's actually quite subtle. Sometimes it works, sometimes it
       | doesn't, depending on which page you are on, what you've already
       | clicked, etc. All part of the fun of frontend web development,
       | ain't it?
        
       | programmarchy wrote:
       | If I'm understanding correctly, this is binding event handlers
       | "just in time" instead of when a component initializes. Isn't
       | that just a tradeoff between working the CPU at load time vs.
       | working the CPU on user interaction?
       | 
       | This doesn't seem like a great tradeoff to me. Sure, maybe you
       | save time during component initialization, but while that is
       | happening the user is digesting the information anyway. Then once
       | they make their decision to act, there's no extra delay to
       | produce the next state. However, with a "just in time" event
       | binding, now the user has to wait (slightly) longer after they've
       | already made their decision, which seems worse.
        
         | zanellato19 wrote:
         | Yeah... This screams of people who never had bad networks. If
         | you are going to add interactivity as a JIT thing, what happens
         | when the user has a shitty connection? You give the impression
         | that the page loaded to the user, but it didn't really load.
         | This is just increasing by a lot the amount of connections the
         | user will have to make. Its _more_ overhead with a bunch of
         | http calls.
        
           | deckard1 wrote:
           | it's all to appease the Google black box. UX always takes a
           | back seat to SEO. Because if there are no users, then no one
           | to irritate with bad UX in the first place. If it weren't for
           | SEO we would have all dropped SSR+hydration long ago.
           | Absolutely no one likes unifying URLs and content and all
           | that shit on two sides of a single app.
        
         | lhorie wrote:
         | Haven't dug too deep, but my understanding is that this doesn't
         | bind event handlers just in time, but instead sets up event
         | delegation from a tiny blocking bootstrapping script, to attach
         | a top-level event handler that catches all events as soon as
         | the first chunk of HTML streams in.
         | 
         | In addition, it sets up an intersection observer. Then
         | depending on when an event happens, it _might_ require
         | downloading that one event handler piecemeal if the event
         | occurred early enough during page load, or if the event is late
         | enough, the action happens instantaneously because the
         | intersection observer already downloaded the handler in
         | anticipation that the user would interact with the element, it
         | being visible and all.
         | 
         | The trade-off is that the download of every other JS thing
         | effectively gets deferred due to fragmentation of how JS gets
         | loaded in the page, but the cleverness of the trade-off is that
         | in typical scenarios, most of that deferred code is not going
         | to be activated by the user in the first place (or at least not
         | in quick succession so as to overload network).
        
       | genzweedsmoker wrote:
        
       | chasd00 wrote:
       | This is confusing to me. From the article it sounds like the
       | javascript is run on the server producing markup. That markup is
       | sent to the browser for rendering then the javascript is
       | requested by the browser. When the javascript arrives it is run
       | again on the browser to re-generate the DOM with event handlers
       | attached. If that is correct then why is the javascript run on
       | the server to begin with and not just sent directly to the
       | browser?
       | 
       | Is the idea to take advantage of the server's horsepower to get
       | something on the screen fast by sending pre-rendered HTML and
       | then wait while the browser runs the code to basically re-create
       | the page for interactivity?
       | 
       | (it's been a while since i've done traditional front-end web dev)
        
         | chrischen wrote:
         | I think most importantly the server can cache requests (cache
         | the generated HTML). This is especially important for public,
         | mostly static pages that one might want to do SEO optimizations
         | for anyways.
         | 
         | Servers are often weaker than many consumer computers anyways,
         | so I don't thin it's because it can render faster than your own
         | browser.
        
           | bacro wrote:
           | >Servers are often weaker than many consumer computers
           | anyways, so I don't thin it's because it can render faster
           | than your own browser.
           | 
           | Isn't this the other way around? I mean a server is supposed
           | to be fast enough to handle a lot of requests.
        
             | chrischen wrote:
             | Well, servers often come with more but slower cores.
        
               | tylerhou wrote:
               | But servers have a much higher power budget compared to
               | phones or most laptops. That's supposedly the target user
               | base for SSR + hydration.
        
               | chrischen wrote:
               | I don't think the purpose of SSR + hydration is to simply
               | move the wait time from first render to server response,
               | or that servers can somehow render faster. To fully yield
               | the benefits you'd have to enable caching, so that the
               | server spits out something _without_ rendering and the
               | client side can simply hydrate.
               | 
               | Caching is not something individual distributed clients
               | can do, which is why the server is the only way able to
               | reasonably take on this role. You can also easily
               | configure nginx to serve just-in-time caching.
        
             | hunterb123 wrote:
             | An individual server is more powerful than one client, but
             | your client computing power multiplies by your user base.
             | 
             | Same reason DDoS attacks are generally more powerful than
             | DoS attacks.
             | 
             | Power in numbers.
        
           | MonaroVXR wrote:
           | >Servers are often weaker than many consumer computers
           | anyways, so I don't thin it's because it can render faster
           | than your own browser.
           | 
           | I'm thinking about that Hacker News article, which had a
           | laptop in the datacenter, because it was much faster on it.
        
         | redbar0n wrote:
         | It is correct, except I think the browser generates the DOM
         | from the HTML, and the JS just attaches event handlers to it.
         | 
         | The reason for the double work is that the context here is
         | SSR/SSG:
         | 
         | <<The re-execution of code on the client that the server
         | already executed as part of SSR/SSG is what makes hydration
         | pure overhead: that is, a duplication of work by the client
         | that the server already did.>>
         | 
         | In client-side rendering (CSR), there isn't double work in
         | rendering the HTML, since the client only does it.
         | 
         | Yes, the idea is to send pre-rendered HTML (by using SSR/SSG).
         | The client doesn't need to re-create the page/HTML, simply
         | hydrate it (attach event handlers). But it is duplicate work
         | and turns out to be a bit expensive to always do it on the
         | initial load.
         | 
         | Hope that helps to clarify.
        
         | brundolf wrote:
         | You get to at least see the content much faster, it's just not
         | interactive for a bit. The benefit is clearest when rendering
         | pages at build time and then serving the HTML over a CDN
         | 
         | But even then, it's definitely still a problem vs sites that
         | don't have to be hydrated. Some people see this approach as a
         | best-of-both-worlds, but in reality it's still a compromise
         | that has costs
        
         | grayrest wrote:
         | This post is part of a broader effort among emerging js
         | frameworks to send less code down to the browser. It's not just
         | bandwidth. The time to parse, compile, and execute the JS can
         | take as long on a phone as the download itself
         | 
         | For a decent fraction of applications a large chunk of the code
         | that's written is to generate non-interactive parts of the app
         | (data fetching, wrappers, component markup, CSS) and the actual
         | code for event handling is relatively small. Hacker News, for
         | example, is a pretty common framework demo since it's simple to
         | write. You need a bit of JS on the comments page for the vote
         | buttons and the comment collapse but if you write HN in a
         | natural way in most component oriented frameworks the bundle
         | coming down is considerably larger and includes all the code
         | for rendering the comments (for example) even though the
         | comments never change and most hydration approaches will put
         | the comments in both the markup and embed a JSON/JS chunk in
         | the page so hydration and the client side render can happen
         | with consistent data. This doubles the size of the page with
         | the overhead of the data half running through some subset of
         | the JS code machinery.
         | 
         | In the case of Qwik, the idea is to do a server side render and
         | then lazy load everything on the client as it's needed. At
         | least that's my understanding, I haven't used the framework
         | beyond a toy project. There are other approaches but to use the
         | HN example, you'd never download the comment collapsing code if
         | you didn't click a collapse button.
        
           | wonnage wrote:
           | You could avoid shipping down the JSX templates but only by
           | promising to never render a comment on the client. That's
           | basically the approach taken by this React Server Components
           | proposal: https://github.com/josephsavona/rfcs/blob/server-
           | components/...
           | 
           | Rails has experimented with this sort of thing in the past;
           | it requires some deep integration with the HTTP server so
           | that clients can request updates to specific chunks of the UI
           | rather than just URLs.
        
             | ryansolid wrote:
             | Yeah RSCs are another approach I'd say that are playing
             | with these sort of approaches. Other notables include:
             | 
             | Marko: https://www.markojs.com Astro: https://astro.build
        
         | tshaddox wrote:
         | > If that is correct then why is the javascript run on the
         | server to begin with and not just sent directly to the browser?
         | 
         | Just the same ordinary reasons to generate HTML on the server:
         | it allows you to support HTTP caching (in a CDN or even browser
         | caching), it (potentially) lets the browser start rendering
         | content much sooner, and it will be viewable by user agents
         | (bots, scrapers, search engines, etc., but also humans) that
         | don't run JavaScript.
        
           | chasd00 wrote:
           | that makes sense, so if you're using http caching
           | appropriately the server side "render" or running of the
           | javascript happens on the first visit and then infrequently
           | thereafter.
        
         | wonnage wrote:
         | > When the javascript arrives it is run again on the browser to
         | re-generate the DOM with event handlers attached.
         | 
         | Not the DOM, but the virtual DOM. Instead of inserting elements
         | (which is expensive), it can just walk the existing server-
         | rendered DOM and attach listeners.
        
         | simulate-me wrote:
         | One reason I like SSR is that you need some form of SSR for
         | public-facing websites anyway. Website previews (like in
         | iMessage, Twitter, etc.) rely on Open Graph tags in the HTML,
         | and these services expect the OG tags to be available without
         | executing any JavaScript. Since you already need this step, you
         | can make loading pages much faster if you inline any data you
         | might have fetched from the client at view time.
        
           | codercatdev wrote:
           | Just one side note here you could also just use SSG, and
           | never need to hit a server unless you rebuild the page in
           | some fashion
        
         | lhorie wrote:
         | Generally speaking, if you approach qwik.js from a 10,000 mile
         | view like you'd normally approach other frameworks, you're
         | going to miss the trees for the forest. One of the axioms where
         | this framework is coming from is the idea of providing React-
         | like developer experience, so yes, there's going to be
         | templates expressed in JS.
         | 
         | Where it gets technical has to do with how the JS gets
         | delivered to the browser. It starts with a small bootstrapping
         | that sets up event delegation, sort of like
         | `document.documentElement.addEventListener('click',
         | becomeAwareOfClicks)`. This happens literally on the first
         | chunk of HTML being streamed in, meaning that the framework is
         | now already aware of clicks happening anywhere in the app, even
         | before HTML <body> is available in JS.
         | 
         | Eventually some HTML will stream in with an attribute that
         | indicates how a click event on an element should be handled.
         | The framework can then quickly determine whether it needs to
         | "hydrate" that event handler: a) if the event was captured by
         | `becomeAwareOfClicks` and b) the intersection observer deems
         | that element is visible and available to DOM manipulation, then
         | c) it can download the relevant handler, meaning it triggers
         | business logic at latest as soon as the intersection observer
         | downloads the handler.
         | 
         | Note that at this point, no other JS has downloaded yet.
         | Eventually it does download it, like every other framework, but
         | the key point is that it can respond to events with actual
         | business logic before the rest of the JS comes down the pipe.
        
       ___________________________________________________________________
       (page generated 2022-04-20 23:01 UTC)