Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hydrate server-rendered apps #48

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open

Conversation

jgaskins
Copy link
Member

@jgaskins jgaskins commented Jun 5, 2016

Previously, server-rendering a Clearwater app involved generating the virtual DOM nodes and replacing what was rendered by the server. This is pretty inefficient, though, because it has to throw away all of the existing server-rendered nodes. Basically, the first Clearwater render was like Turbolinks, which isn't as fast as you might think.

This PR lets Clearwater handle the existing DOM nodes as if they were artifacts of a previous Clearwater render. The best thing about this is that Clearwater doesn't even have to be what rendered it on the server.

In order to accomplish this, I had to add another JS library. This required shaving at least 3 yaks to enable us to use NPM for all that, but it ends up making our JS assets (current and future) easier to manage. Unfortunately, it also means we're stuck using NPM.

Before this, updating the virtual-dom library was a mess: I included my own flavor of it (includes an important performance optimization not yet merged into the original) which was stored on one of my local machines, but not anywhere else. That made it impossible for anyone but me to update that library and even I couldn't do it if I was away from that machine. This PR streamlines that by using NPM and browserify, pulling both of the required runtime dependencies from external sources. This means that Clearwater's canonical virtual-dom library is now at clearwater-rb/virtual-dom.

jgaskins added 2 commits June 5, 2016 01:46
Previously, server-rendering a Clearwater app involved generating the
virtual DOM nodes and *replacing* what was rendered by the server. This
is pretty inefficient, though, because it has to throw away all of the
existing server-rendered nodes. This can be prohibitively expensive on
slower devices.

This commit lets Clearwater handle the existing DOM nodes as if they
were artifacts of a previous Clearwater render.
@jgaskins
Copy link
Member Author

jgaskins commented Jun 5, 2016

Aaaaand I broke the build.

The good news is that, when I say "we're stuck using NPM", I mean just to build the virtual-dom library.

More good news is that this PR also removes the virtualDom global variable we were using before for virtual-dom. That dependency is now entirely self-contained within our Ruby bindings for it. Encapsulation FTW.

@jgaskins
Copy link
Member Author

jgaskins commented Jun 5, 2016

Looks like this is causing issues after the first render if the first node inside the app-container node isn't the same type as your app's root node. Specifically, the app will only client-render once.

This is a problem with apps that:

  • Have no server-rendered app content
  • Render directly to the body
  • Load JS inside the body

This is due to the fact that the first DOM node in the body in these cases is a script tag (and your app's root node is probably a div). Since every Clearwater app I build meets these 3 criteria in the beginning (at least the ones that are the page's primary content), this is a use case I'd rather not break. :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant