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

Adds back SSR #126

Merged
merged 15 commits into from
Aug 6, 2024
Merged

Adds back SSR #126

merged 15 commits into from
Aug 6, 2024

Conversation

mikesol
Copy link
Owner

@mikesol mikesol commented Aug 1, 2024

No description provided.

@jterbraak
Copy link
Collaborator

Still have to step through all the new SSR steps but my first impressions are:

  • ScopeDepth can go, with Ancestry we should have enough information to skip destruction. Maybe move the destruction skip into the implementation of DOMInterpret
  • I have a hunch that we can still reduce the surface area of DOMInterpret

@mikesol
Copy link
Owner Author

mikesol commented Aug 1, 2024

Still have to step through all the new SSR steps but my first impressions are:

  • ScopeDepth can go, with Ancestry we should have enough information to skip destruction. Maybe move the destruction skip into the implementation of DOMInterpret
  • I have a hunch that we can still reduce the surface area of DOMInterpret

Cool, I'll try my best to sub in Ancestry for ScopeDepth. As for moving the destruction skip, it's a bit above my pay grade currently as I don't quite understand that part of the code yet, but I can study it!

Re DOMInterpret, absolutely, I think we can squeeze it down more. Basically, anything that's not directly touching the DOM , that's not different between the DOMInterpret, and that's not strictly necessary for SSR/hydration can go.

Another thing the PR needs is an algo to slim down the size of the generated HTML. It's currently bloated with too many deku-related attributes, and it's possible to traverse the DOM & eliminate all of the atts that won't be used during hydration. That'll also make hydration much faster, as we'll be able to use the isBoring field to skip hydrating some chunks entirely.

@jterbraak
Copy link
Collaborator

Now that you mention them, could you add an explanation of isBoring and isLucky? I'm assuming that "isBoring"~ pure and "isLucky" ~ unnested dyn element?

@mikesol
Copy link
Owner Author

mikesol commented Aug 1, 2024

Now that you mention them, could you add an explanation of isBoring and isLucky? I'm assuming that "isBoring"~ pure and "isLucky" ~ unnested dyn element?

So isLucky I'm not sure (I couldn't find it in this PR), but isBoring = pure, meaning that we can skip hydration. All the info to determine that is baked into the DOM & the cache, so it can be done after the html is extracted and fed to hydration. In the tests I don't do that yet, but I'll write an algo that does. Also, anything that's boring or a descendent thereof will have its data-deku-ssr attributes and text markers removed.

Lastly, SSR needs jsdom to work, but if you're running it from the deku repo this gets installed when you do pnpm i.

@mikesol mikesol requested a review from jterbraak August 1, 2024 13:12
@mikesol
Copy link
Owner Author

mikesol commented Aug 1, 2024

I'm going over ScopeDepth and, just to make sure I understand, could you point me to where it's reset to 0? I see where 1 is added, and I also see where it's 0'd out at the toplevel, but I'm not sure where it's set to 0 again. I see a ScopeDepth 0 in remove for useDynWith, but I'm not sure if/how that turns into a lifecycle. Could you give me a bit more info? Thanks!

@mikesol
Copy link
Owner Author

mikesol commented Aug 1, 2024

Nvm, I understand now. The ScopeDepth for lifecycle is monotonically increasing, which means it'll be 0 up until we hit our first element. By mergeing it with ScopeDepth 0 in dyns, we guarantee that remove fires if a dyn fires.

I can definitely recreate this logic using ancestry. dispose can likely be Effect Unit and lifecycle can likely be Poll Unit as I'll be able to embed ancestry in the dispose effect 👍

@mikesol
Copy link
Owner Author

mikesol commented Aug 2, 2024

@jterbraak ScopeDepth is now removed and Ancestry is used.

@mikesol
Copy link
Owner Author

mikesol commented Aug 3, 2024

The optimizer is now added.

The best way to see the result is the tests. Now, every test in index.test.js runs in its SSR+hydration and "normal" variants. Furthermore, there's a new test suite in Main.purs that makes assertions about the SSR output. You can see that the DOM is quite lean in terms of extra identifiers, and the isBoring cache assertions show how hydration is aggressively optimized.

@mikesol
Copy link
Owner Author

mikesol commented Aug 3, 2024

@mikesol
Copy link
Owner Author

mikesol commented Aug 4, 2024

Added a client routing example as well: https://github.com/mikesol/vike-deku-client-routing.

@mikesol
Copy link
Owner Author

mikesol commented Aug 5, 2024

Migrated the docs to ssr to test it out (will migrate back if this isn't merged). They deploy fine on vercel. https://deku-documentation.vercel.app . The generated html via view-source is pretty complete, it picks up on almost 100% of the pages & healthy chunks are ignorable, so the rendering is faster than the previous docs 🚀

@mikesol
Copy link
Owner Author

mikesol commented Aug 6, 2024

Merging so this doesn't go stale as I won't have time in the next few days. Thoroughly tested & deku docs are deployed with it 🚀

@mikesol mikesol merged commit 276f48a into main Aug 6, 2024
1 check passed
@mikesol mikesol deleted the ssr branch August 6, 2024 05:21
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.

2 participants