Open fitzgen opened 6 years ago
I would like to see a middleware/framework which does server-side rendering of pages. I've never seen a "perfect" solution to the server-side rendering problem, and up until now only the nodejs platform has really even offered it as a possibility at all.
The "holy grail" would have these properties:
1) The raw content from the server consists of fully rendered static HTML 2) The initial HTML contains "normal" hyperlinks 3) Dynamic content is loaded with the initial value rather than just being a placeholder 4) The page works as completely as possible without javascript 5) If the javascript is loaded, it doesn't need to fully re-render the page after load 6) If the javascript is loaded, "normal" hyperlinks become client-side routing hooks 7) Correct caching headers are returned, so that rendered pages can be cached across requests without compromising security
The way I see this working is with a single "application state" object which is JSON serializable and includes the entire virtual DOM. When a request comes in, the request handler initialises the state, and the initial render performed. Next, the state is serialised onto the end of the HTML. When the javascript is loaded, it deserialises this blob of application state, and continues rendering from there, and this should be completely transparent from the actual components being rendered, so that they don't even realise they were sent over the wire. Caching headers would be sent based on the "initial state" that the request handler returned.
There are powerful Javascript-frameworks like Angular or Ember, which form rich ecosystems of display components and other kind of add-ins. It will take many years for something equivalent to develop in Rust.
Clients need to do check consistency themselves to avoid making the user wait for the server roundtrip. Servers cannot rely on the consistency of the data they receive. They need to check again, to make certain the data is not compromised. Display and user interaction however need not be integrated with or even aware of the existence of the server. They are solely client side problems.
The pragmatic approach to client/server integration thus seems writing single page applications (SPA) in existing frameworks but writing the model and its consistency checks only once in rust. Some parts of code would be marked to be compiled twice. Once for the server and once for the client, not only conforming to WASM but also to the target javascript framework. This marked code would need to have very few dependencies.
@fitzgen Maybe even blurring the lines and transparently running futures on etiher the server or client?
Just FYI, thanks to help from @CryZe and @Diggsey (and myself), stdweb now has excellent support for both JavaScript Promises and Rust Futures (and of course converting JavaScript Promises into Rust Futures).
So if anybody wants smooth integration between the client and server, this should help.
As far as client-side DOM rendering libraries go, I am personally strongly in favor of virtual DOM based on observables (not DOM diffing!). I have used this technique to great success in JavaScript, and I think it will work very well in Rust too.
The major benefits of observables are:
It doesn't need to do DOM diffing (so it's much much faster!). It's generally only very slightly slower than raw DOM operations. In particular, changes are constant time rather than linear to the virtual DOM tree size.
Because it's so blazingly fast, you can actually do full composable 60 FPS animations with it, which is something that DOM diffing struggles heavily with.
It makes it crystal clear at both the type and run-time level which things are static (unchanging) and which things are dynamic (changing at runtime). This makes the code faster, but more importantly it makes the code easier to understand.
It makes it easy to create local encapsulated state (which is much harder with most DOM diffing systems).
It handles event listeners much better (DOM diffing struggles with anything which can't be tested for equality, and closures can't be tested for equality).
It doesn't need hacks like the key
attribute.
I've been planning to make a prototype demonstrating the idea, but I've gotten sidetracked with a bunch of pull requests on stdweb.
@Pauan this looks really promising. The arguments related to vdom
(kinda feels like react) and I always wanted to try this out with rust / wasm in general. exicting times
ahead.
Would be very interesting to see / help with that...
Hello! @Pauan I'm also hoping to experiment with observable/computed based web framework for Rust. I very much like Vue.js and intend to use many of it's ideas as prior art. Perhaps we can collaborate?
I have started work on implementing zero-cost virtual DOM and zero-cost signals / observables for Rust.
It's not ready to publish yet, but you can find the code in the rust-dominator
repo.
It works correctly, but it doesn't compile right now (it requires stdweb version 0.4.0
, which isn't released yet).
Let's discuss any questions / features / bugs on that repo.
Oh nice, rust-dominator is very cool! I really like what you've done with the signal / state.
For the moment I might keep typing on my own castle, I am aiming for something which has a mix of both yew and dominator about it: vdom diffing with a splash of observables / reactivity mixed in to simplify updates. If my ideas turn out to be trash I'll come out to lend a hand as all these projects mature. Exciting times ahead indeed 😃
I've been going over rust+wasm discussions across the internet and one idea that has popped up a few times is a framework that straddles across the server and the client, providing tight and smooth integration.
What exactly does this mean? Built on top of tokio and yew? Hyper and stdweb? Maybe even blurring the lines and transparently running futures on etiher the server or client? You figure it out for us! :)
One interesting aspect is that this pretty much sidesteps the whole packaging and bundler integration story, since you'd have full control of the end-to-end pipeline.
Would be awesome to see some experiments in this area.