Nextjs使用Mantine出现未样式化内容闪烁(FOUC)问题

12
我切换到了 Mantine 并按照 这个 方法解决了 FART(颜色主题不精确闪烁)问题,但是网页出现了新问题。在页面渲染之前会出现未样式化的组件闪烁。如何解决这个问题? 我查看了 Next.js 的 Github,发现有一些 FOUC 问题,但解决方案是添加 <script>0</script>,这对我没用。 这个 bug 只在生产环境中存在,在开发环境中运行正常。 示例:https://gotrip.vercel.app 如果您没有看到闪烁,请复制链接并将其粘贴到浏览器中。
import Document, { Html, Head, Main, NextScript } from "next/document";
import { createGetInitialProps } from "@mantine/next";

const getInitialProps = createGetInitialProps();

export default class _Document extends Document {
    static async getInitialProps(ctx) {
        const initialProps = await Document.getInitialProps(ctx);
        return { ...getInitialProps, ...initialProps };
    }

    render() {
        const setInitialTheme = `
      function getUserPreference() {
        if(window.localStorage.getItem('theme')) {
          return window.localStorage.getItem('theme')
        }
        return window.matchMedia('(prefers-color-scheme: dark)').matches 
          ? 'dark' 
          : 'light'
      }
      document.body.dataset.theme = getUserPreference();
    `;
        return (
            <Html>
                <Head />
                <body>
                    <script dangerouslySetInnerHTML={{ __html: setInitialTheme }} />
                    <Main />
                    <NextScript />
                </body>
            </Html>
        );
    }
}

你能描述一下这个闪存吗?我看不到它。我已经在使用Firefox 97和Chrome 95的Private/Incognito/Guest窗口中尝试了。 - Codebling
如果我不使用隐身模式并设置暗黑模式,然后关闭并重新打开,我会看到整个页面闪烁白色。这是你所说的那个问题吗?还是它只出现在某个组件上? - Codebling
@Megan 你确定这是和 OP 一样的问题吗?我在你的网站上看到了这个问题,但在 OP 的网站上没有看到。 - Codebling
@Codebling 我也这么认为,我们都在使用Mantine库。此外,在NextJS线程中建议的解决FOUC问题的方法,即添加<script>0</script>,对我也没有起作用。 - Megan
@Megan 我不确定这是同一个问题。你正在使用SSR(根据Mantine开发人员的说法,这是你闪烁的原因),但OP没有。我可以在你的网站上看到闪烁,而在OP的网站上我看不到。 - Codebling
显示剩余2条评论
2个回答

2

在查看了这个Github问题后,我对自己的项目应用了三种解决方案,因为我曾经遇到过类似的问题。

如果有人遇到了这个问题,请尝试以下方法,应该可以解决。

  1. 如果您还没有这样做,请按照这个说明配置您的Next.js项目以使用Mantine。 (注意:我建议您也应用可选步骤)

  2. 如果您在Vercel上托管项目或进行本地开发,请使用“yarn build”而不是npm

  3. 如果您正在使用12.1.6版本,请将Next.js降级到12.1.5或升级到更新的版本(@canary版本)

希望这能解决您的问题。这是我的第一个答案,请多包涵 :)


1
指令链接无法使用。 - blockhead

-1

这是我如何解决这个问题的方法。

首先,在您的_document.js中,使您的根Html元素最初的opacity = 0

<Html lang='en' style={{ opacity: 0 }}>

然后,在您的_app.js中,将此属性更改为仅在挂载后可见:

useEffect(() => {
  document.documentElement.style.opacity = 1
}, [])

希望这能帮到你 :-)

如果您这样做,就不会向用户发送任何(可视化的)预渲染/服务器端渲染的HTML(就像create-react-app一样),这是Next最重要的功能之一。 - maxeth
从SEO角度来看?(请注意,已经从交替使用可见性属性更改为透明度) - Allan of Sydney
我认为这可能对SEO不利,尽管在两种情况下呈现的HTML文档仍然存在,因此即使它在视觉上被隐藏,搜索引擎也可以解析它而无需JS。对我来说更重要的是(并非所有用例都相关),您甚至不能在浏览器中启用JS而轻松使用该网站。只有少数用户通过Tor-Browser /扩展程序有意禁用JS,但JS代码有时会因许多原因而无法下载/执行(例如,许多移动浏览器应用程序在慢速连接上关闭JS,扩展程序可能会破坏JS代码等)。 - maxeth
是的,我也有这个担忧,但我想所有的标记都会被爬取到。我找不到任何确切的答案来说明实际的可见性是否会影响SEO。我的大部分工作都包含动画、预加载器、页面转换等等。所以像这样的东西几乎总是必须的。 - Allan of Sydney

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接