next.js icon indicating copy to clipboard operation
next.js copied to clipboard

Make `antd.css` become an internal stylesheet to avoid the the CSS flickering issue in the `with-ant-design` example

Open evanxd opened this issue 5 years ago • 3 comments

Make antd.css become an internal stylesheet to ensure that the stylesheet will be loaded before the page rendering and avoid the CSS flickering issue.

Fixes #22819.

evanxd avatar Apr 22 '21 04:04 evanxd

Hi @leerob

The next.js example in material-ui reop basically does the same approach to avoid the CSS flickering issue, make the material-ui styles as an internal stylesheet, like below: https://github.com/mui-org/material-ui/blob/next/examples/nextjs/pages/_document.js#L74-L79

<style
  key="emotion-style-tag"
  data-emotion={`css ${styles.ids.join(' ')}`}
  // eslint-disable-next-line react/no-danger
  dangerouslySetInnerHTML={{ __html: styles.css }}
/>,

I have another idea to solve the CSS flickering issue, but I'm not sure it's a better solution. We can hide the page until the external antd CSS file is loaded, and then display the page, which means we can do something like below:

<head>
  <link rel="preload" href="antd.min.css" as="style" onload="this.rel = stylesheet; document.querySelector('body').setAttribute('style', 'visibility: visible');" />
</head>
<body style="visibility: hidden">
</body>

But the cons of the hiding body element approach are:

  • It doesn't work when users disable JavaScript
  • It doesn't work if the URI of the CSS file is broken

To be honest, compare to the hiding body element approach, I more prefer the internal CSS approach, it more clear and easier. Does anyone have other better ideas?

evanxd avatar Apr 23 '21 04:04 evanxd

Ah! If we can handle the JavaScript disability situation for the hiding body element approach, we can make the page visible in the <noscript /> element. So we can do something like below to fix the problem.

<head>
  <link rel="preload" href="antd.min.css" as="style" onload="this.rel = stylesheet; document.querySelector('body').setAttribute('style', 'visibility: visible');" />
  <noscript><style>body { visibility: visible }</style></noscript>
</head>
<body style="visibility: hidden">
</body>

Does this make the hiding body element approach become a better solution?

evanxd avatar Apr 23 '21 05:04 evanxd

I also think this solution is not ideal. Perhaps a solution which does not involve using _app.js and _document.js would be the best one.

dryleaf avatar Apr 30 '21 01:04 dryleaf

Whether this problem has not been solved, the latest official example still has this problem

ClearSeve avatar Dec 05 '22 07:12 ClearSeve

Closing as stale – if you would like to continue this, please open a new PR and we can take a look. Thank you so much! 🙏

leerob avatar Jan 04 '23 15:01 leerob