【问题标题】:FOUC when using @material-ui/core with NextJS/React将 @material-ui/core 与 NextJS/React 一起使用时的 FOUC
【发布时间】:2019-08-26 22:21:25
【问题描述】:

我的简单NextJS页面是这样的(结果可以在https://www.schandillia.com/查看):

/* eslint-disable no-unused-vars */

import React, { PureComponent, Fragment } from 'react';
import Head from 'next/head';
import compose from 'recompose/compose';
import Layout from '../components/Layout';
import { withStyles } from '@material-ui/core/styles';
import Button from '@material-ui/core/Button';

const styles = {
  root: {
    textAlign: 'center',
    paddingTop: 200,
  },
  p: {
    textTransform: 'uppercase',
    color: 'red',
  },
};

class Index extends PureComponent {
  render() {
    const { classes } = this.props;
    const title = 'Project Proost';
    const description = 'This is the description for the homepage';
    return (
      <Fragment>
        <Head>
          <title>{ title }</title>
          <meta name="description" content={description} key="description" />
        </Head>
        <Layout>
          <p className={classes.p}>amit</p>
          <Button variant="contained" color="secondary">
            Secondary
          </Button>
        </Layout>
      </Fragment>
    );
  }
}

export default withStyles(styles)(Index);

我正在从@material-ui/core 库中导入一堆组件来设置我的项目的样式。我还有一个本地样式定义分配给 style 常量。

这里似乎发生的事情是我的样式没有在服务器上呈现,这就是为什么加载时提供的文件是 sans 样式的。然后 CSS 由客户端代码呈现。结果,出现了一连串无样式的内容,持续了将近一秒钟,足够引人注意。

有什么办法可以解决这个问题吗?整个代码库可供参考https://github.com/amitschandillia/proost/tree/master/web

【问题讨论】:

  • 如果您在应用加载时观察元素检查器,您会看到它在 中注入了 MUI 样式标签。我会玩弄 MUI 如何使用 JSS 的配置。这是来自 MUI 文档的有趣信息页面,具体部分开始提供调整这方面性能的建议:material-ui.com/customization/css-in-js/#html-comment
  • 我知道我的样式被注入到了` 部分。但我的问题是这种注入只发生在 client 而不是 server。这就是导致FOUC的原因。我需要一些方法来确保在推送页面之前将样式信息注入服务器。
  • 不,我正在使用 NextJS 从头开始​​构建。
  • 如果你不会为你的生产构建做任何不同的配置并且你使用react-create-app创建你的应用程序,我建议使用react-create-app的react-scripts build。我为此花了很多时间配置一个 webpack,然后发现它已经附带了一个简单但有用的构建工具 ootb

标签: material-ui next.js


【解决方案1】:

我在尝试使用 material-ui 制作我的应用程序的生产版本时遇到了类似的问题。我设法通过像这样添加JSS Provider 来解决:

import JssProvider from "react-jss/lib/JssProvider";

class App extends Component {
  render() {
    <JssProvider>
      *the rest of your material-ui components*
    </JssProvider>
  }
}

【讨论】:

  • 你必须对每一页都这样做吗?或者我可以将我的&lt;Main /&gt;&lt;NextScript /&gt; 元素包装在_document.jsx&lt;JssProvider /&gt; 中一次,然后在每个单独的页面(Index.jsx、About.jsx 等)中忘记它吗?
  • 我有很多组件只加载了两个主要组件,和你一样。所以我只在这些主要的上使用它。我想如果你的所有组件都在&lt;Main /&gt;&lt;NextScript /&gt; 中被引用,那么就在它们上面,而忘掉个别的。至少这对我有用
  • 好的,我现在查看了您的代码,在您的情况下,您在同一个 RootDocument 组件上使用它们。您可以将 &lt;JSSProvider&gt; 包裹在 &lt;Html lang="en"&gt; 上,或者甚至在 RootDocument 组件内,如果您正在使用更多 Material-ui 样式的组件
【解决方案2】:

这是解决方案 - https://github.com/mui-org/material-ui/blob/master/examples/nextjs/pages/_document.js

基本上,您需要做的就是将服务器端类名与客户端同步。上面的链接显示了您需要采取哪些措施来解决该问题。

【讨论】:

    猜你喜欢
    • 2017-10-26
    • 1970-01-01
    • 1970-01-01
    • 2020-04-24
    • 2020-01-20
    • 2021-01-14
    • 2021-03-22
    • 2020-04-03
    • 1970-01-01
    相关资源
    最近更新 更多