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

SSR refs breaks the hydration in concurrent requests #310

Merged
merged 5 commits into from
Dec 12, 2020

Conversation

andrzejewsky
Copy link
Contributor

Hello Nuxt team,

Recently, I've got quite an interesting issue with server-side rendering and composition API. It works perfectly unless you have higher traffic on your website.

Seems like multiple requests at the same time affects the ssrRefs that are passed to the __NUXT__ object. The reason why requests are mixed up is this line: https://github.com/nuxt-community/composition-api/blob/main/src/ssr-ref.ts#L17 - you always refer to the global object that is shared across incoming requests. The Nuxt handle this in the following way:

  1. Request is coming
  2. Call globalPlugin and reset global data object
  3. call ssrRefs and modify the data (data points in this case to ssrRefs in __NUXT__)
  4. Send markup to user

Now, when we have multiple calls, it may look like this:

  1. Request is coming
  2. Call globalPlugin (reseting data)
  3. Call ssrRefs
  4. Another request is coming
  5. Call globalPlugin (reseting data) <- we just wiped up data from the previous request
  6. Call ssrRefs
  7. The First request finished with empty or mixed data (ssrRefs, broken hydration)
  8. The Second request finished normally

Steps to reproduce:

  1. yarn & yarn build & run fixtures in prod mode: yarn fixtures:prod
  2. go to /ssr-ref
  3. Run siege (or other load test tool) eg: siege -d 1 -c 10 -H "Cache-Control: no-cache" http://localhost:3000
  4. when you refresh the page, you can see that sometimes prefetched-result is empty (prefetched-)

Solution:
Always use context, to pass and modify the data that are related to the given request. Using context requires vue instance so you can't use your composition API out of the components eg. above component or in plugins.

The fix I created is using context, but still, allows you to use a global object as well - so you can use composition API outside of the setup, but we should keep in mind that can cause some issues (maybe worth to mention in docs?)

@vercel
Copy link

vercel bot commented Dec 2, 2020

This pull request is being automatically deployed with Vercel (learn more).
To see the status of your deployment, click below or on the icon next to each commit.

🔍 Inspect: https://vercel.com/nuxt-community/composition-api/dbkbzcrc1
✅ Preview: https://composition-api-git-ssr-ref-concurrent-fix.nuxt-community.vercel.app

@danielroe
Copy link
Member

This looks good to me - will review shortly.

@danielroe
Copy link
Member

@andrzejewsky Apologies for making some bigger changes without coming back to you first. Primarily this is just to get this merged sooner; I would welcome a future PR if you think there's something missing or this can be improved 👍

Copy link
Member

@danielroe danielroe left a comment

Choose a reason for hiding this comment

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

Thanks for this PR - great work ❤️

@danielroe danielroe merged commit 61a3b55 into nuxt-community:main Dec 12, 2020
@andrzejewsky
Copy link
Contributor Author

thanks @danielroe ! actually, we even have confirmed that PR bu using this as a fix for some of our projects - works fine with higher traffic as well

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants