Live data from Hacker News

Show HN: Percy – A Rust and WebAssembly isomorphic virtual DOM implementation

github.com

11–20 of 53 posts

Re: Show HN: Percy – A Rust and WebAssembly isomorphic virtual DOM implementation

#11
post #2

can you write an app in just once file and mark what can run in the client and what must only run on the server?

As in an example app?

If you don't need server side rendering you can have one Rust file but you also need a JS file to initialize the WebAssembly module. So just one file isn't reasonably possible.

For a server side rendered app you need to have a cargo workspace with 3 crates (they can be in the same repo so not a huge deal).

One crate is a `cdylib` that you compile to WebAssembly to serve your app to the client. This is a light wrapper around your actual application.

One crate is your actual application.

And one crate is your server, which is also a light wrapper around your actual application.

That server side rendering structure can be found here - https://github.com/chinedufn/percy/tree/master/examples/isom...

But in terms of a super minimal example without server side rendering.. I'll be working on adding one (along with updating the current example)!

Re: Show HN: Percy – A Rust and WebAssembly isomorphic virtual DOM implementation

#12
post #3

Hi chinedufn, this looks very interesting. I am at the same stage as you re. "I REALLY want to use this for everything ...". I see you're using wasm_bindgen quite a bit, but from a cursory look at the code; I can't figure out something: I can see how you're using wasm in the front-end, but could you please elaborate a bit more about in the backend? I presume that your backend is Rust based? I spent last weekend porti…

Sure!

The backend is pretty much this (messy) file - https://github.com/chinedufn/percy/blob/master/examples/isom... .

It

1. Pulls in your application crate 2. Initializes your app (more or less sets initial state 3. Renders your app's virtual DOM into an HTML string 4. Serves the HTML to the client, along with the initial state serialized into JSON in a script tag (using serde-json) 5.Also serves the WASM script and the JS that initializes the WASM

So that's your server crate. Then your client crate also pulls in your same application crate and you compile it to WebAssembly and that's what runs browser side.

Feel free to let me know if any of that was poorly explained!

Re: Show HN: Percy – A Rust and WebAssembly isomorphic virtual DOM implementation

#13
post #8

Earlier quoted context omitted.

An isomorphic virtual DOM is much like an inverted-index homomorphic shadow DOM, but instead of using a shadowed mapping they virtualize the original elements themselves .

Can someone ELI5 what an inverted-index homomorphic shadow DOM is? TIA

In a regular DOM there's just a tree of elements, this makes many operations tedious, e.g. finding elements with a given set of classes and so on. So with an inverted-index shadow DOM you get another DOM with element shadows and an index of element properties back to the shadow elements (making it an inverted index). Then simple boolean retrieval can be used instead of DOM traversal. Much more efficient. The actual reason why you want to use shadowing instead of direct-mapped nodes/elements is shadowing enabling E2C (element change coalescing) meaning instead of shadow element changes directly transferring over to a change of the actual DOM element you can batch changes on shadow elements together and change a bunch of DOM elements in one go, which avoids unpartitioned (and therefore wasteful) re-renders by the browser engine.

Re: Show HN: Percy – A Rust and WebAssembly isomorphic virtual DOM implementation

#17
post #2

can you write an app in just once file and mark what can run in the client and what must only run on the server?

As in an example app? If you don't need server side rendering you can have one Rust file but you also need a JS file to initialize the WebAssembly module. So just one file isn't reasonably possible. For a server side rendered app you need to have a cargo workspace with 3 crates (they can be in the same repo so not a huge deal). One crate is a `cdylib` that you compile to WebAssembly to serve your app to the client. T…

what i want to see is to have all logic to be centered around features, and have a framework compile the server side and client server out of one logical piece of code, if that even makes sense.

a bit like in the old days of php when you'd have the serverside code and html rendered in their, but this time nearly everything is running on the client unless the client can't be trusted.

you could have some kind of ring system, where something can never run on the client right up to always run on client, but all in one file.

but maybe that's nasty.

Re: Show HN: Percy – A Rust and WebAssembly isomorphic virtual DOM implementation

#18
post #8

Earlier quoted context omitted.

Can someone ELI5 what an inverted-index homomorphic shadow DOM is? TIA

In a regular DOM there's just a tree of elements, this makes many operations tedious, e.g. finding elements with a given set of classes and so on. So with an inverted-index shadow DOM you get another DOM with element shadows and an index of element properties back to the shadow elements (making it an inverted index). Then simple boolean retrieval can be used instead of DOM traversal. Much more efficient. The actual r…

damn, this sounds awesome, specially the part about batching renders, much like 'vsync' but for DOM.

thank you for the info!

Re: Show HN: Percy – A Rust and WebAssembly isomorphic virtual DOM implementation

#19

How does this compare to the Yew framework?

Yew is awesome and just knowing that something like that was possible inspired Percy. I also looked at Yew's `html!` macro when figuring out how Percy's could / should work.

One difference is that Yew is powered by stdweb and Percy is powered by wasm-bindgen.

I'm personally SUPER bullish on wasm-bindgen because it's been designed from day 1 to be able to take advantage of the host bindings proposal when it materializes.

Host bindings tl;dr is that instead of needing to go through JS to interact with browser APIs you can interact with them directly.

Another difference is that to my knowledge Yew doesn't support server side rendering ( which was why I couldn't use it even though I wanted to :( ).

Without having used Yew I don't want to comment any further than those high level differences.

I can say that a big focus of Percy is to be a grab bag of modules / tooling for frontend Rust web apps with a major focus of you being able to swap out the parts that you think are bad for other peoples' better implementations. That dream isn't realized yet.. but I think that Rust's generics / traits could make this feel very clean!

Re: Show HN: Percy – A Rust and WebAssembly isomorphic virtual DOM implementation

#20
post #18

Earlier quoted context omitted.

In a regular DOM there's just a tree of elements, this makes many operations tedious, e.g. finding elements with a given set of classes and so on. So with an inverted-index shadow DOM you get another DOM with element shadows and an index of element properties back to the shadow elements (making it an inverted index). Then simple boolean retrieval can be used instead of DOM traversal. Much more efficient. The actual r…

damn, this sounds awesome, specially the part about batching renders, much like 'vsync' but for DOM. thank you for the info!

(Ok, before anyone goes running off telling their colleagues about this great new tech: I literally made all of this up on the fly except the batching stuff. That's actually one of two reasons why this whole shadow-DOM-stuff exists. The other is encapsulation. I think this whole thread is a most beautiful demonstration of Poe's law in its original form.)
Post reply on HN