fix: refetch should wait for page component to start streaming#1516
fix: refetch should wait for page component to start streaming#1516rmarscher wants to merge 5 commits intowakujs:mainfrom
Conversation
It's using the window.location to test that refetch does not resolve before the requested page has started streaming. There might be a more direct way to test that.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. |
commit: |
|
My primary method of testing is to do this: pnpm i
cd packages/waku
pnpm run compile
cd ../../e2e/fixtures/create-pages
pnpm i
pnpm run devIncrease the setTimeout in SlowComponent in e2e/fixtures/create-pages/src/components/LongSuspenseLayout.tsx to a few seconds so it's easier to observe. Open https://localhost:3000/long-suspense/1 and click on a link. I added temp console logging to the resolved console.log('Elements promise resolved', {
elements,
rscPath,
routeData,
isStatic,
prefetchOnly,
});I can see that the page element is a React.lazy component. So... the problem is that functions to fetch a new page or refetch the current page use We need a function in router/client that wraps fetchRsc, finds the requested page element and awaits it's lazy promise before resolving. |
What would be the timing of resolving the elements? elements.then(() => console.log('elements resolved'))Isn't it the timing you want? If React.lazy delays even after that, it feels tricky. (edit) I'm probably missing something because |
|
I might be missing some context but how does current behavior compare with Next.js? For example in this demo, navigation between two tabs updated urls immediately while showing |
That looks like a case where you want the UI to eagerly show a loader. In my use case, I want to continue showing the existing content - maybe with a loading indicator - until the next page has loaded -- which seems to work except the window.location is updated and page scroll are happening as soon as the response returns from the server. I haven't read the NextJS code to see how they handle RSC payloads in their router, but I generated a demo and it has the desired behavior that I'm unable to acheive with Waku. The URL is not updated until the page has loaded. https://github.com/rmarscher/nextjs-long-suspense-demo |
|
I found fetchServerResponse and some code where it is matching rsc elements to route segments. I didn't see where it's awaiting the page segment yet... but it does seem that the inner router suspends indefinitely after routing... so maybe that doesn't re-render until the page component has loaded somehow. |
|
It's quite hard to follow next.js but I think This allows |
I understand now that this is outside the scope of The It would be nice if there was a way to watch for the the page component to send something before resolving and updating the scroll state and window.history. I wonder if React Router uses the same process as NextJS. |
|
I experimented with "history mutation as effect" approach on vite rsc starter template. Here is the demo https://github.com/hi-ogawa/reproductions/tree/main/vite-rsc-coordinate-history-and-transition I didn't go through their entire |
Thanks for doing that. I'm interested to try extending it to return a layout and a page component in the rsc response. It's helpful to work with your minimal repro. |
Starting with a failing test that uses window.location to demonstrate that refetch resolves early before the requested page has started streaming.
Once we figure out how to solve it, this will close #1437