feat: use cache request provider support in ssr layer#368
Merged
Conversation
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
react-server-docs | 0a2172f | Mar 26 2026, 01:26 PM |
⚡ Benchmark Results
Legend🟢 > 1% improvement | 🔴 > 1% regression | ⚪ within noise margin Benchmarks run on GitHub Actions runners (shared infrastructure) — expect ~5% variance between runs. Consistent directional changes across multiple routes are more meaningful than any single number. |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #368 +/- ##
=======================================
Coverage ? 93.93%
=======================================
Files ? 2
Lines ? 2275
Branches ? 686
=======================================
Hits ? 2137
Misses ? 138
Partials ? 0
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
e241a72 to
0a2172f
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Add full
"use cache: request"provider support across the RSC, SSR, and client (browser) environments, enabling per-request deduplication of expensive computations that works transparently across rendering layers.Problem
React Server Components and SSR run in separate environments (often separate threads). When a function marked with
"use cache: request"is called from both a server component and a client component during the same request, the function bodyexecutes multiple times — once per environment. There's no mechanism to share the cached result across the RSC → SSR boundary, and no way to hydrate the value in the browser without prop-drilling.
Solution
This PR introduces a cross-environment shared cache protocol with two modes:
SharedArrayBuffer-based append-only log withAtomics.wait/Atomics.notifyfor lock-free cross-thread communication. The RSC thread writes serialized cache entries; the SSR worker thread blocksuntil entries arrive.
Map-backed cache with the sameread/writeAPI, used when RSC and SSR run on the same thread.Values are serialized using new synchronous RSC Flight protocol helpers (
syncToBuffer/syncFromBuffer) added to@lazarv/rsc, preserving all RSC-supported types (Date, Map, Set, RegExp, URL, typed arrays, React elements, etc.) across thethread boundary.
Key changes
@lazarv/rsc— Synchronous Flight serializationsyncToBuffer(value)— Synchronously serializes a value into an RSC Flight payload buffer (server)syncFromBuffer(buffer)— Synchronously deserializes an RSC Flight payload buffer (client/SSR)@lazarv/react-server/cache— Request cache infrastructurerequest-cache-shared.mjs(new) —SharedArrayBufferprotocol (createSharedRequestCache,attachSharedRequestCache) and in-process fallback (createInProcessRequestCache)cache/index.mjs— Server-sideuseCachegains a dedicated request-provider fast path with in-process dedup, thenable annotation for React'suse(), andSharedArrayBufferwrite-throughcache/ssr.mjs(new) — SSR-specificuseCachethat reads from the shared cache (SAB or in-process) and returns pre-resolved thenables for synchronoususe()consumptioncache/client.mjs— Browser-sideuseCachegains hydration support: reads fromself.__react_server_request_cache_entries__(injected inline script), deserializes withsyncFromBuffer, and returns stable pre-resolved thenablesSSR handlers — Per-request cache lifecycle
lib/dev/ssr-handler.mjsandlib/start/ssr-handler.mjs— Create a per-requestStorageCache+ shared cache (SAB or in-process) and inject them into the rendering context viaREQUEST_CACHE_CONTEXT/REQUEST_CACHE_SHAREDsymbols
server/render-dom.mjs— SSR worker integrationContextStorageand a dedicatedRequestCacheStorageALS<script>tags for browser hydration, usingObject.assignfor incremental injection within streamed Suspense boundariesno-hydrateare excluded from the inline scriptlib/plugins/use-cache-inline.mjs— Build plugin"use cache: request"in SSR environment builds (not just client)no-hydratebare flag andhydrate=falseparameterserver/request-cache-context.mjs(new)AsyncLocalStoragefor the request cache reader, independent of the mainContextStoragechain — ensures cache modules find the reader even when the ALS chain breaks across bundled edge modulesno-hydratedirectiveFunctions can opt out of browser hydration while still benefiting from RSC↔SSR deduplication:
The cached value is shared between RSC and SSR during rendering, but is not embedded in the HTML — the client component will recompute the value in the browser.
Documentation
Tests
7 new integration tests covering: