Code Monkey home page Code Monkey logo

Comments (7)

marvinhagemeister avatar marvinhagemeister commented on June 9, 2024 5

Blowing away the DOM may work from a technical point of view but is a pretty jarring user experience. It will nearly always lead to white disrupting flash when the DOM is destroyed and build up again.

from crank.

yurynix avatar yurynix commented on June 9, 2024 2

@benjamingr
The main problem I see, is not how to render the components, IMO, that's already done in the HTML renderer.
The problem is IMO, how to attach event handlers and "forward" the component's generator function to the proper "step" on client side after we got the HTML string from the server.

from crank.

botverse avatar botverse commented on June 9, 2024 1

To add two more arguments to why I think @marvinhagemeister is right on saying that this will led to a jarring user experience without hydrating:

  1. Recreating the whole DOM tree twice, it's styles, reflows and compositing it's an expensive operation that leads for the browser to have a large impact in the first time to interactive, this is obviously not noticeable in the small example, but very noticeable for the user in a page with 1500 nodes.

  2. Also when the user triggers an event in the pre-rendered dom, it will not translate to the new tree and it's listeners, thing that will work seamlessly in a hydrated React page once the listeners are installed. This will happen quite a lot because the pre-rendered tree might be shown in the screen while the browser is still downloading the whole bundle, processing the javascript and executing it, this process can be as quick as ~0.5 seconds in a desktop with local access to the bundle but as long as few seconds in a mobile.

If the issue goes down to user experience, this is a must that has to be taken into account, otherwise crank will be unlikely to be a choice for anything that needs ssr.

To the point from @yurynix of how to forward the generators to the right step, this can be let to be the responsibility of the architecture of the app, and the libraries that hold the serialized state from the server.

For example if you are driving both the ssr and client renders based on fetch state, you can:

  1. While in ssr and hydrating, in the server you wait for the responses before fulfilling the fetch promise and in the client you give that response immediately when hydrating from the serialized cache.

  2. While reacting to user events in the already hydrated app in the client, you might want to fulfil the fetch promise immediately upon request with the request metadata when there is a cache miss, to leave the app the opportunity to show the loading intermediate component. For this the async pattern you need is a generator, to be able to re-render when the response arrives

from crank.

benjamingr avatar benjamingr commented on June 9, 2024

I just learned about this project so taking a stab:

In both React and crank components hold state and are impure - in crank that state is managed by the language itself (through generators) rather than reinventing the wheel (through array pushing and popping in hooks or through instance state with "fake classes" in classes).

Holding the state as local variables means you can use tooling the language makes available to you instead of rolling something "specific to SSR" kind of how async functions with MobX are easier than Redux because they leverage language tooling.

This means SSR is as simple as just calling .render on a component. Components work the same way but the generator only runs as long as you want.

Taking the code example of an async component:

async function QuoteOfTheDay() {
  const res = await fetch("https://favqs.com/api/qotd");
  const {quote} = await res.json();
  return (
    <p>
      “{quote.body}” – <a href={quote.url}>{quote.author}</a>
    </p>
  );
}

In order to SSR this - you just run it as is (with isomorphic-fetch) or if you want to cache the result or otherwise treat it differently on the server - you just inject the server parts and mock them on the server side.

from crank.

benjamingr avatar benjamingr commented on June 9, 2024

That is, even in regular react SSR is slightly different because components are "less stateful", managing that state in regular JavaScript and just discarding the generators makes things easier.

from crank.

benjamingr avatar benjamingr commented on June 9, 2024

Oh I see what you're talking about now - that depends on how the stores and state is implemented. I'm not sure if the framework already supports hydration - but hydration would require "cooperation" from the stores in order to "progress the generator automatically" on the client.

from crank.

workingjubilee avatar workingjubilee commented on June 9, 2024

Cross-quoting from Reddit:

Yeah! Right now, you can render components to strings using the HTML renderer, and it works with stateful/async components out of the box! These are the early days of this library, and I plan on creating some kind of meta-framework like Next.js or Svelte’s Sapper, if someone doesn’t do it for me. I looked into creating one, but they almost always involve some kind of advanced webpack magic that I don’t really understand yet.
In regards to hydration, this might be harder to implement given the current internals of the renderer, but my current thinking is what even is the point of hydration? Like, React has a seperate function for reusing existing DOM nodes, but if the outputs are the same, why do we care that the DOM nodes are reused versus blowing away those nodes and rerendering the same thing on the client? I know that in React, server/client rendering mismatches are kind of annoying, so I think I may experiment with the blow it all away and don’t care about mismatches approach.

—Brian Kim

Some responses:

Don’t forget about playing videos. If you return video markup from the server then init the client side, it would interrupt the users experience.

Thank you for the details!
I don't know all the reasons for rehydration but one of the personally more importent ones is: Animations / CSS Transitions will trigger again without the rehydration thingy.

To which he said "excellent points" roughly.

I am not sure that "blow it all away" would not work, however, if the SSR'd rendering framework requested an initial holding state for animations and video, and then loaded in the actual animation/video when it threw the explosives... essentially demanding a clear landing site for the app's dynamic components. Bad for certain kind of pages, ofc, but those pages are often the ones which are most dependent on JS in the first place, so the gains of SSR with hydration (providing a static webpage quickly using a dynamic framework, then enabling a swift transition using the app's diffing powers) were already low.

from crank.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.