Skip to content

Running the Hydrogen render process in child_process is slow #49

@MadLittleMods

Description

@MadLittleMods

Spawning from #44 which added more tracing and made it obvious how much slow child_process is over the base vm script.runInNewContext(...)


Soo, how slow is running in the child_process?

In #36, we started wrapping our whole rendering Hydrogen vm flow in a child_process because using a Node.js vm context doesn't have a way to stop the process (it just keeps running). With the child_process we can kill it when we choose after we get the HTML result.

Now with this timing from #44, we can also get some insight into how bad of a performance hit it is to run the Hydrogen render in the child_process is. It seems to be a lot slower: ~50ms vs 360ms.

// Use the `vm` directly to see how fast it is
const _renderHydrogenToStringUnsafe = require('../hydrogen-render/3-render-hydrogen-to-string-unsafe');
const hydrogenHtmlOutput = await _renderHydrogenToStringUnsafe({ /* renderData */ });

(see server/README.md for enabling tracing in the app)

Without child_process (renderHydrogenToString took 43ms) With child_process (renderHydrogenToString took 397ms)
Jaeger trace where renderHydrogenToString takes 43ms Jaeger trace where renderHydrogenToString takes 400ms

I wonder how much of the slowness is the disk read every time it reads in the script to run?

We could test this theory by inlining the script directly in https://github.com/matrix-org/matrix-public-archive/blob/fd00fec6f1f91ea55fe59b05f0658318c2738f42/server/hydrogen-render/3-render-hydrogen-to-string-unsafe.js#L95-L98

Should we switch away from child_process?

Maybe.

We could use the vm script.runInNewContext(...) timeout option and just accept that it will be living for 5 seconds (or whatever we timeout we choose) before it dies. We already choose to kill the child_process after 5 seconds if it takes too long since we expect the Hydrogen render part to be fast.

Or maybe abuse the vm script.runInNewContext(...) breakOnSigint option and send a SIGINT to kill it. Need to be careful not to kill our main process.

Is it possible just to reset and render Hydrogen over and over with the same VM context? We could do a similar thing and keep the child_process alive and share for all renders.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-SSRServer-side rendering (backend)A-performanceWhat is slow, what made it faster and more efficient?A-tracingOpenTelemetry tracing (spans, timing, observability)T-EnhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions