sx-http: native SSR + island placeholders — homepage 158ms, 2MB RSS
Switch SSR from SX adapter to native Sx_render.render_to_html. Islands that fail SSR emit <span data-sx-island="name"> placeholders instead of recursing into client-only bodies. Eliminates the <home symbol error cascade that made the homepage render 23s. Performance (warm, single process): Homepage: 131-191ms TTFB (was 202ms on Quart) — faster Geography: 203-229ms TTFB (was 144ms on Quart) — close Reactive: 155-290ms TTFB (was 187ms on Quart) — similar Memory: 2MB RSS (was 570MB on Quart) — 285x reduction Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1484,13 +1484,15 @@ let http_render_page env path =
|
|||||||
| _ -> serialize_value body_result
|
| _ -> serialize_value body_result
|
||||||
in
|
in
|
||||||
let t2 = Unix.gettimeofday () in
|
let t2 = Unix.gettimeofday () in
|
||||||
(* Phase 2: SSR — render to HTML *)
|
(* Phase 2: SSR — render to HTML using native renderer.
|
||||||
|
Native Sx_render handles islands as placeholders when SSR fails,
|
||||||
|
avoiding deep recursion into client-only island bodies. *)
|
||||||
let body_html =
|
let body_html =
|
||||||
try
|
try
|
||||||
let body_exprs = Sx_parser.parse_all body_str in
|
let body_exprs = Sx_parser.parse_all body_str in
|
||||||
let body_expr = match body_exprs with
|
let body_expr = match body_exprs with
|
||||||
| [e] -> e | [] -> Nil | _ -> List (Symbol "<>" :: body_exprs) in
|
| [e] -> e | [] -> Nil | _ -> List (Symbol "<>" :: body_exprs) in
|
||||||
sx_render_to_html body_expr env
|
Sx_render.render_to_html body_expr env
|
||||||
with e ->
|
with e ->
|
||||||
Printf.eprintf "[http-ssr] failed: %s\n%!" (Printexc.to_string e); ""
|
Printf.eprintf "[http-ssr] failed: %s\n%!" (Printexc.to_string e); ""
|
||||||
in
|
in
|
||||||
|
|||||||
@@ -258,9 +258,10 @@ and render_list_to_html head args env =
|
|||||||
| Component c when c.c_affinity = "client" -> "" (* skip client-only *)
|
| Component c when c.c_affinity = "client" -> "" (* skip client-only *)
|
||||||
| Component _ -> render_component v args env
|
| Component _ -> render_component v args env
|
||||||
| Island _i ->
|
| Island _i ->
|
||||||
(* Islands: SSR via the SX render-to-html from adapter-html.sx.
|
(* Islands: try SSR via the SX render-to-html from adapter-html.sx.
|
||||||
It handles deref/signal/computed through the CEK correctly,
|
It handles deref/signal/computed through the CEK correctly,
|
||||||
and renders island bodies with hydration markers. *)
|
and renders island bodies with hydration markers.
|
||||||
|
On failure, emit a placeholder — client hydrates from SX source. *)
|
||||||
(try
|
(try
|
||||||
let call_expr = List (Symbol name :: args) in
|
let call_expr = List (Symbol name :: args) in
|
||||||
let quoted = List [Symbol "quote"; call_expr] in
|
let quoted = List [Symbol "quote"; call_expr] in
|
||||||
@@ -269,9 +270,9 @@ and render_list_to_html head args env =
|
|||||||
(match result with
|
(match result with
|
||||||
| String s | RawHTML s -> s
|
| String s | RawHTML s -> s
|
||||||
| _ -> value_to_string result)
|
| _ -> value_to_string result)
|
||||||
with e ->
|
with _e ->
|
||||||
Printf.eprintf "[ssr-island] ~%s FAILED: %s\n%s\n%!" _i.i_name (Printexc.to_string e) (Printexc.get_backtrace ());
|
(* Placeholder — client will hydrate this island *)
|
||||||
"")
|
Printf.sprintf "<span data-sx-island=\"%s\"></span>" _i.i_name)
|
||||||
| Macro m ->
|
| Macro m ->
|
||||||
let expanded = expand_macro m args env in
|
let expanded = expand_macro m args env in
|
||||||
do_render_to_html expanded env
|
do_render_to_html expanded env
|
||||||
|
|||||||
Reference in New Issue
Block a user