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

[docs] Fix global styles leaking on different pages #25855

Merged
merged 9 commits into from
Apr 22, 2021

Conversation

mnajdova
Copy link
Member

@mnajdova mnajdova commented Apr 20, 2021

As per emotoin's documentation, the cache should be re-created per request (see the note https://emotion.sh/docs/ssr#extractcritical). So far we've been reusing the same cache instance, which was leading to global styles leaking on different pages.

Preview: https://deploy-preview-25855--material-ui.netlify.app/components/grid/#interactive

Fix #24970

@mui-pr-bot
Copy link

mui-pr-bot commented Apr 20, 2021

No bundle size changes

Generated by 🚫 dangerJS against 37644f9

@oliviertassinari oliviertassinari added bug 🐛 Something doesn't work docs Improvements or additions to the documentation labels Apr 20, 2021
@mnajdova

This comment has been minimized.

@oliviertassinari
Copy link
Member

@mnajdova The changes break the SSR output, on all the pages. I assume the extractCritical used on the server is overridden by the second RTL/LTR cache.

@oliviertassinari
Copy link
Member

oliviertassinari commented Apr 20, 2021

We will need to update our Next.js examples.

@mnajdova
Copy link
Member Author

mnajdova commented Apr 20, 2021

@oliviertassinari can you check now after af27d29, I remember that I was exporting cacheLtr so that I can reuse it in createEmotionServer, but I don't remember why.

Found it - #22731 we needed this so that SSR will work :\

@mnajdova mnajdova marked this pull request as draft April 20, 2021 18:12
@mnajdova
Copy link
Member Author

mnajdova commented Apr 20, 2021

@mnajdova The changes break the SSR output, on all the pages. I assume the extractCritical used on the server is overridden by the second RTL/LTR cache.

Yeah I noticed, not sure how to make both of them work at the same time. Looks like they are contradicting, or I am doing something wrong.. Probably the second :D

@oliviertassinari
Copy link
Member

oliviertassinari commented Apr 20, 2021

@mnajdova We could, for instance, only mount the RTL cache after the hydration. In JSS I had to use a special prop to allow the nesting of multiple StyleProvider to work with SSR, for this very configuration.

@mnajdova
Copy link
Member Author

@mnajdova We could, for instance, only mount the RTL cache after the hydration. In JSS I had to use a special prop to allow the nesting of multiple StyleProvider to work with SSR, for this very configuration.

Interesting, ok I'll try this tomorrow.

@mnajdova mnajdova marked this pull request as ready for review April 21, 2021 10:39
@mnajdova
Copy link
Member Author

@oliviertassinari I believe everything should be fixed now. I was missing CacheProvider in _document.js. I've tested locally

  • RTL & LTR switching works
  • Page rendered with Disabled JavaScript works
  • styles are respecting the ssr style tags that we are creating

Let's wait for the prod build and verify and I think it should be good to go


const { extractCritical } = createEmotionServer(cacheLtr);
const cache = createCache({ key: 'css', prepend: true });
Copy link
Contributor

Choose a reason for hiding this comment

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

Hm, this doesn't look like creating the cache per render - unless in your setup this file is reexecuted each render. Don't you have global styles leaking between pages right now?

Copy link
Member Author

Choose a reason for hiding this comment

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

Good catch! I reverted back the getCache method. Thanks :)

Copy link
Member

@oliviertassinari oliviertassinari left a comment

Choose a reason for hiding this comment

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

👍 to @Andarist's comment, the cache is still global, it leaks: https://deploy-preview-25855--material-ui.netlify.app/components/grid/#interactive (Cell 1 is font-family Inter, our branding)

@mnajdova
Copy link
Member Author

👍 to @Andarist's comment, the cache is still global, it leaks: https://deploy-preview-25855--material-ui.netlify.app/components/grid/#interactive (Cell 1 is font-family Inter, our branding)

When I was cleaning up I reverted the changes for getCache 🤦

Co-authored-by: Olivier Tassinari <olivier.tassinari@gmail.com>
@@ -9,8 +9,9 @@ import { pathnameToLanguage } from 'docs/src/modules/utils/helpers';
import { themeColor } from 'docs/src/modules/components/ThemeContext';
import createCache from '@emotion/cache';

const cache = createCache({ key: 'css', prepend: true });
const { extractCritical } = createEmotionServer(cache);
const getCache = () => createCache({ key: 'css', prepend: true });
Copy link
Contributor

Choose a reason for hiding this comment

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

This shouldn't break anything (I think), but the overall recommendation is to use custom keys when creating caches and the "css" is kinda a default one.

Copy link
Member Author

@mnajdova mnajdova Apr 21, 2021

Choose a reason for hiding this comment

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

Should this be identical with the one we use on the client? For example use mui on both places?

PS: I will leave this for a follow up PR 👍

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, definitely it should be the same - this is used for rehydrating stuff and so on.

Copy link
Member

@oliviertassinari oliviertassinari left a comment

Choose a reason for hiding this comment

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

It's not working <style id="emotion-server-side" data-emotion="css "></style> is empty. See https://validator.w3.org/nu/?doc=https://deploy-preview-25855--material-ui.netlify.app/components/grid/#interactive

Adding cache.compat = true; will probably do it

@mnajdova
Copy link
Member Author

mnajdova commented Apr 21, 2021

It's not working <style id="emotion-server-side" data-emotion="css "></style> is empty. See https://validator.w3.org/nu/?doc=https://deploy-preview-25855--material-ui.netlify.app/components/grid/#interactive

Adding cache.compat = true; will probably do it

It was broken with 2adb0fa, once the global styles leaks were solved, this broke 😕

So basically I am at this:

  • new cache instance - solves leaks 👍 , breaks SSR 👎
  • global cache instance - introduces leaks 👎 , solves SSR 👍

I tried using cache.compat=true, but it didn't solve the issue.

Let me open additional PR that fixes the SSR and compare and see what are the changes and what we can do. I am running in circles now...

Edit: opened #25863 so that we can test my theory

@mnajdova
Copy link
Member Author

So on https://deploy-preview-25863--material-ui.netlify.app/ (PR #25863) ssr is fixed, but the leaking is still there

@oliviertassinari
Copy link
Member

@mnajdova Please have a look at my latest commit. It seems to fly.

@mnajdova
Copy link
Member Author

@mnajdova Please have a look at my latest commit. It seems to fly.

I could still repro the leaking:

@mnajdova
Copy link
Member Author

@oliviertassinari last try, I've tried to incorporate these changes together with the changes from emotion-js/emotion#2334 in #25690

I think everything works over there, but I may be missing something (I can't trust myself on this one anymore):
https://deploy-preview-25690--material-ui.netlify.app/components/avatars/#main-content

  • The emotion's ssr style tag looks like contains the styles:

  • I could not spot the issue with the leaking
  • rtl works

@oliviertassinari
Copy link
Member

oliviertassinari commented Apr 21, 2021

I could still repro the leaking:

@mnajdova Oh yes correct. This time, the leak is not on the server-side, but on the client-side. We end up with:

Screenshot 2021-04-21 at 17 27 35

This looks like a different issue, isn't the same as emotion-js/emotion#2158 where the old global isn't removed from the DOM when unmounted?

@oliviertassinari
Copy link
Member

oliviertassinari commented Apr 21, 2021

last try […] I think everything works over there

@mnajdova I corroborate 👌

@mnajdova
Copy link
Member Author

mnajdova commented Apr 21, 2021

last try […] I think everything works over there

@mnajdova I corroborate 👌

Good! I started to lose my mind over this one 😄 I'd say let's merge this one, and after upgrading emotion, we can verify again that this new scenario works.

Edit: Or we can wait and merge only #25690 once we have new release of emotion

@oliviertassinari
Copy link
Member

oliviertassinari commented Apr 21, 2021

@mnajdova IMHO these two issues are independent, happy with whatever order

@mnajdova
Copy link
Member Author

Ok, I'll merge this one and rebase #25690

@mnajdova mnajdova merged commit 47f36ca into mui:next Apr 22, 2021
@oliviertassinari
Copy link
Member

🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 🐛 Something doesn't work docs Improvements or additions to the documentation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[docs] Missing body styles from CssBaseline in light mode
4 participants