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

ssr: streaming with suspense #187

Closed
wants to merge 1 commit into from
Closed

Conversation

roman01la
Copy link
Collaborator

@roman01la roman01la commented Nov 17, 2024

Initial implementation of streaming SSR with suspense boundaries, as described in reactwg/react-18#37

  • example.core includes web server implementation
  • example.ui includes UI components with suspense boundaries

Running the demo

  • server cd dom && clojure -A:dev -M -m example.core
  • client cd dom && clojure -A:dev -M -m shadow.cljs.devtools.cli watch ssr

Explainer

When server rendering on JVM, data dependencies are resolved synchronously, which blocks delivery of HTML to the client. Moreover, it introduces a waterfall of requests, making HTML generation even slower.

Instead, it's proposed to implement out of order streaming. We can run suspended UI concurrently (UIx elements wrapped in suspense component) and return initial HTML immediately. Once the suspended UI resolves, chunks of HTML are streamed to the client together with bits of JS that insert the streamed HTML into DOM at specified locations where "suspended" UI is declared.

Together with HTML and JS we also stream the data retrieved in suspended components, so that React on the client can pick it up and correctly hydrate HTML into interactive UI.

Using this approach, we are able to keep co-located data and prevent degraded user experience.

TODO

  • $! error handling
  • more robust data sharing between server and client
    • make sure it's compatible with repl workflow
  • tests

@roman01la roman01la force-pushed the roman/ssr-suspense-streaming branch 2 times, most recently from 6b05354 to c2b2f1d Compare November 18, 2024 16:09
@accounts-pitch-io
Copy link

master:
react x 10977 ops/s, elapsed 911ms
uix x 7605 ops/s, elapsed 1315ms
helix x 7651 ops/s, elapsed 1307ms
reagent x 5447 ops/s, elapsed 1836ms

PR:
react x 9506 ops/s, elapsed 1052ms
uix x 7547 ops/s, elapsed 1325ms
helix x 7758 ops/s, elapsed 1289ms
reagent x 5814 ops/s, elapsed 1720ms

@roman01la roman01la force-pushed the roman/ssr-suspense-streaming branch from c2b2f1d to b5d96b9 Compare November 18, 2024 22:25
@accounts-pitch-io
Copy link

master:
react x 10977 ops/s, elapsed 911ms
uix x 7605 ops/s, elapsed 1315ms
helix x 7651 ops/s, elapsed 1307ms
reagent x 5447 ops/s, elapsed 1836ms

PR:
react x 11074 ops/s, elapsed 903ms
uix x 8764 ops/s, elapsed 1141ms
helix x 8525 ops/s, elapsed 1173ms
reagent x 6317 ops/s, elapsed 1583ms

@roman01la roman01la force-pushed the roman/ssr-suspense-streaming branch from b5d96b9 to b0aeee5 Compare November 19, 2024 00:00
@accounts-pitch-io
Copy link

master:
react x 10977 ops/s, elapsed 911ms
uix x 7605 ops/s, elapsed 1315ms
helix x 7651 ops/s, elapsed 1307ms
reagent x 5447 ops/s, elapsed 1836ms

PR:
react x 11507 ops/s, elapsed 869ms
uix x 8749 ops/s, elapsed 1143ms
helix x 8446 ops/s, elapsed 1184ms
reagent x 6090 ops/s, elapsed 1642ms

@roman01la roman01la force-pushed the roman/ssr-suspense-streaming branch from b0aeee5 to 531e146 Compare November 19, 2024 00:26
@accounts-pitch-io
Copy link

master:
react x 10977 ops/s, elapsed 911ms
uix x 7605 ops/s, elapsed 1315ms
helix x 7651 ops/s, elapsed 1307ms
reagent x 5447 ops/s, elapsed 1836ms

PR:
react x 11468 ops/s, elapsed 872ms
uix x 8606 ops/s, elapsed 1162ms
helix x 8703 ops/s, elapsed 1149ms
reagent x 6443 ops/s, elapsed 1552ms

@roman01la roman01la force-pushed the roman/ssr-suspense-streaming branch from 531e146 to 1fbcaec Compare November 19, 2024 00:36
@roman01la roman01la force-pushed the roman/ssr-suspense-streaming branch from 1fbcaec to 10af761 Compare November 19, 2024 00:37
@accounts-pitch-io
Copy link

master:
react x 10977 ops/s, elapsed 911ms
uix x 7605 ops/s, elapsed 1315ms
helix x 7651 ops/s, elapsed 1307ms
reagent x 5447 ops/s, elapsed 1836ms

PR:
react x 12151 ops/s, elapsed 823ms
uix x 9497 ops/s, elapsed 1053ms
helix x 8726 ops/s, elapsed 1146ms
reagent x 5882 ops/s, elapsed 1700ms

@accounts-pitch-io
Copy link

master:
react x 10977 ops/s, elapsed 911ms
uix x 7605 ops/s, elapsed 1315ms
helix x 7651 ops/s, elapsed 1307ms
reagent x 5447 ops/s, elapsed 1836ms

PR:
react x 12285 ops/s, elapsed 814ms
uix x 9217 ops/s, elapsed 1085ms
helix x 9033 ops/s, elapsed 1107ms
reagent x 6158 ops/s, elapsed 1624ms

@roman01la roman01la closed this Jan 8, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants