Crank: Stop blowing away the children of DOM nodes which we render into

Created on 21 Sep 2020  路  4Comments  路  Source: bikeshaving/crank

Currently when we call renderer.render(<App />, node), all of the children of node which Crank doesn鈥檛 own are blown away. This means that rendering into document.body will blow away the rest of the document. I would like Crank to work more cooperatively with the existing DOM; maybe we can keep track of the first and last nodes which we have rendered into a node and only render in that range.

enhancement

All 4 comments

Will a fix for this allow an hydration render? Currently I'm having issues trying to identify when dom nodes were rendered with HTMLRenderer.

https://github.com/cristianfalcone/pedal/issues/1

@cristianfalcone Can you elaborate a little on what you鈥檙e looking for? Perhaps you could add a data-ssr attribute to your routes for SSR code perhaps, which is erased or set to false on the client?

I still think that the heroic effort of reusing HTML-generated DOM nodes, and making sure they match between server and client during the initial handoff of the page is mostly unnecessary, as I鈥檓 quoted as saying in this issue (https://github.com/bikeshaving/crank/issues/34). Blowing away those nodes and creating new ones is fine for most use-cases, and I can think of workarounds for media elements and FOUC issues, so I haven鈥檛 been prioritizing it. Until someone creates a concrete demo of a UX issue which is caused by not reusing nodes and proves that there are no possible workarounds, I鈥檓 inclined to believe hydration is a waste of effort.

This specific issue is less about hydration and more just about being a good DOM citizen. I want to be able to call renderer.render() with document.body and not blow away everything else which was in the body element. I鈥檝e been working with content editables more recently, which poses a similar issue, how should Crank behave when a rendered DOM node鈥檚 children is mutated by something besides the renderer. The common thread between all these issues is dealing with DOM nodes that are unknown to Crank, and I鈥檇 like to come up with a coherent philosophy at some point for how we deal with them, in a way that isn鈥檛 just blowing up like React does.

Thanks for trying out Crank! I鈥檝e been gearing up to create a similar sort of SSR solution but hit a hard wall when I came to the issue of bundling. I think I have a good grasp about what routing, navigation, and some of the other stuff should look like, but just haven鈥檛 really gotten to writing all of the code and bringing it together, and I鈥檝e more or less been frustrated by everything from the current state of node/deno and their http servers, to the fact that no bundler seems to have a nice programmatic API. I鈥檓 happy to share my thoughts on routing or SSR or even bundling in a GitHub Discussion or by email. I鈥檒l try to look through pedal soon!

Ah I just realized your point while thinking about this while trying to go to sleep. If we implemented this behavior, we wouldn鈥檛 be able to blow away DOM nodes anymore, so rendering into SSR rendered trees would potentially create duplicate applications under the root node. Gotta think some more about this and maybe consider hydration then. Big sigh haha.

Thanks for you comments @brainkim!! Glad you realize my point (I'm not that good with english). What I wanted to accomplish was exactly that, being able to reuse server rendered components. I managed to use a global flag for SSR as you suggested, but if Crank would support hydration, I wouldn't have to serialize fetch data on the server and parse that on client side in order to rebuild the component without calling fetch on client side (which I'm currently doing: https://github.com/cristianfalcone/pedal/blob/master/src/routes/article.jsx#L10, https://github.com/cristianfalcone/pedal/blob/master/src/components/document.jsx#L4, https://github.com/cristianfalcone/pedal/blob/master/src/client.jsx#L13). It'll be a matter of returning a <Copy /> of the server rendered component when running on the client with the SSR flag (and because I'm calling the component code, components will also have events attached if any, which was a concern in #34).

Regarding Pedal POC, there's no much code in there, I'm just using two really small libraries apart from Crank, https://github.com/lukeed/polka and https://github.com/lukeed/navaid, as backend and frontend routers, respectively. You'll find out they are single file libraries with a few lines of code which both share the same router path matcher (polka is compatible with express middlewares, which is a big plus). And I'm bundling for client and server side with https://github.com/rollup with dynamic imports for code spliting (app routes are lazy loaded). So if you want to take a look, it won't take you too much time. If you want to take full ownership of that repo or use the same idea as a base for another project, it's ok too, I'd be happy to see what you could do with that.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

GormanFletcher picture GormanFletcher  路  3Comments

lazeebee picture lazeebee  路  5Comments

waynebaylor picture waynebaylor  路  3Comments

lukejagodzinski picture lukejagodzinski  路  4Comments

dfabulich picture dfabulich  路  4Comments