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

Keep prerender component tree the same as regular render tree #7760

Merged
merged 36 commits into from
Mar 27, 2023

Conversation

Tobbe
Copy link
Member

@Tobbe Tobbe commented Mar 5, 2023

React 18's tree diffing works differently compared to React 17.

This PR changes the logic so that we use the same code for both pre-render and regular rendering to a much greater extent.

Fixes #7757

@Tobbe Tobbe added the release:fix This PR is a fix label Mar 5, 2023
@replay-io
Copy link

replay-io bot commented Mar 5, 2023

16 replays were recorded for 37d7acb.

image 0 Failed
image 16 Passed
    requireAuth graphql checks
          ```
          locator.waitFor: Target closed
          =========================== logs ===========================
          waiting for locator('.rw-form-error-title').locator('text=You don\'t have permission to do that') to be visible
          ============================================================
          ```
        </ol>
      </details>
      <li><a href=https://app.replay.io/recording/0243e34c-0efd-436a-888a-02c9cbd8863d>useAuth hook, auth redirects checks</a></li>
      <li><a href=https://app.replay.io/recording/14a95fa2-3535-47ef-9309-2e9e235e3353>Check that a specific blog post is prerendered</a></li>
      <li><a href=https://app.replay.io/recording/14d89f4d-9d6c-4452-8815-f73658d0f438>Check that about is prerendered</a></li>
      <li><a href=https://app.replay.io/recording/56b06fc9-9395-4cda-b7e5-151925865331>Check that homepage is prerendered</a></li>
      <li><a href=https://app.replay.io/recording/e22fed4c-a556-4ef1-9753-12f97bb2dc49>Check that meta-tags are rendering the correct dynamic data</a></li>
      <li><a href=https://app.replay.io/recording/4b69396d-3837-4f53-a6f3-768068b63303>Check that you can navigate from home page to specific blog post</a></li>
      <li><a href=https://app.replay.io/recording/f8d4f5e3-a149-44c5-8732-37697445e11d>Waterfall prerendering (nested cells)</a></li>
      <li><a href=https://app.replay.io/recording/9ce38e85-922c-4491-b14d-e59903d77205>RBAC: Admin user should be able to delete contacts</a></li>
      <li><a href=https://app.replay.io/recording/35346d1f-854b-4cb9-8d18-a89da2ac27f5>RBAC: Should not be able to delete contact as non-admin user</a></li>
      <li><a href=https://app.replay.io/recording/eba4e661-5f56-4592-971c-70821b00fb17>Smoke test with dev server</a></li>
      <li><a href=https://app.replay.io/recording/2aa697e1-1cfc-439c-a8a2-d22887a2d1cd>Smoke test with rw serve</a></li>
      <li><a href=https://app.replay.io/recording/588cc350-8e2b-47b3-bd5f-5b415e2119bc>Loads Cell mocks when Cell is nested in another story</a></li>
      <li><a href=https://app.replay.io/recording/2d80a6eb-dc93-4162-8648-047f92faeaf2>Loads Cell Stories</a></li>
      <li><a href=https://app.replay.io/recording/be932815-87f4-48d7-aa6d-0b4f59a4ba9d>Loads MDX Stories</a></li>
      <li><a href=https://app.replay.io/recording/a2138776-4f5e-43dd-a04f-84ff4c949a9d>Mocks current user, and updates UI while dev server is running</a></li>
      

View test run on Replay ↗︎

@Tobbe Tobbe force-pushed the tobbe-prerender-react18 branch from 4d0eff9 to 52b6166 Compare March 18, 2023 11:44
@Tobbe Tobbe mentioned this pull request Mar 18, 2023
Tobbe and others added 5 commits March 19, 2023 10:43
- update babel plugin to add webpack chunk name
- remove server markup
- revert hydrate logic
- insert chunk in prerendered html file
@jtoar
Copy link
Contributor

jtoar commented Mar 21, 2023

Next steps: make sure tests still account for #4948 while refactoring.

return NamedCell
return (props: CellProps) => {
return (
<Suspense fallback={<div>Loading suspense...</div>}>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🙌🏻

Do we want to allow for a custom fallback?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to do some more investigations and experiments, but my initial impression is that the fallback isn't used by React in the very specific circumstances we're using it here

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there is value in custom fallbacks.

Looking at the <Suspence> docs, there are examples with varying degrees of specificity ( e.g. BigSpinner vs AlbumsGlimmer )

Copy link
Contributor

@thedavidprice thedavidprice Mar 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 to custom fallbacks. But I think Tobbe is correct that the fallback actually be used for this specific case.

If we're incorrect, we can add/improve in follow on.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just did this to confirm:
image

That console.log never shows up in the browser console. We only use <Suspense> to tell React to not try to match the contents of cells when rehydrating prerendered pages. (This behavior is new in renderToString for React 18)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When we switch/upgrade to renderToPipeableStream we'll have to revisit this

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From the new React docs https://react.dev/reference/react/Suspense#displaying-a-fallback-while-content-is-loading (scroll down to Note)

Only Suspense-enabled data sources will activate the Suspense component. They include:

  • Data fetching with Suspense-enabled frameworks like Relay and Next.js
  • Lazy-loading component code with lazy

Apollo Client is not yet Suspense-enabled, so rendering cells will not cause <Suspense> to suspend, and therefore the fallback will never be rendered.

Suspense (and SSR) support in Apollo is tracked here: apollographql/apollo-client#10231

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI we've got suspense support in our latest 3.8.0-alpha.x releases, so you can test it out in a beta/alpha here if it helps. Let us know how we (the Apollo Client team) can support you!

Just as a status:
We've got some changes that will make useSuspenseQuery work with useDeferredValue and startTransition. We will be exploring how to get streaming cache updates working in SSR coming up next, so I'm hopeful that once you've got renderToPipeableStream working, you'll be able to hook it up to the primitive we export from the library to get it working.

Hope that helps!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc @dac09 @KrisCoulson

Great to hear @jerelmiller! This PR isn't blocked. But other priority work in progress will need Apollo Client support. We'll loop back as needed. Thanks.

@jtoar jtoar merged commit 0063292 into redwoodjs:main Mar 27, 2023
@redwoodjs-bot redwoodjs-bot bot added this to the next-release milestone Mar 27, 2023
@jtoar jtoar added release:breaking This PR is a breaking change and removed release:fix This PR is a fix labels Mar 27, 2023
@jtoar jtoar modified the milestones: next-release, v5.0.0 Mar 27, 2023
@Tobbe Tobbe deleted the tobbe-prerender-react18 branch April 10, 2023 06:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
release:breaking This PR is a breaking change
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Bug]: prerender causes page to be duplicated/rendered twice in RW projects using React18
5 participants