We are using NextJS and Material-UI for our site, and upon loading the pages, it gives a FOUC. I've narrowed the problem down to the fact that the JS loads faster than the .css file, so I was wondering if there was a way to preload the .css file? All of our pages use the same .css file which is located under /pages/styles.css
Here is /pages/_app.js
if that's any help:
// pages/_app.js
import { Provider } from 'next-auth/client'
import { createMuiTheme } from '@material-ui/core/styles';
import { ThemeProvider } from '@material-ui/styles';
import styles from './styles.css'
import Layout from '../ponents/layout'
import Head from 'next/head'
const theme = createMuiTheme({
palette: {
primary: {
main: "#2196f3", // blue
},
secondary: {
main: "#d3d3d3", // gray
},
},
});
export default function _App ({ Component, pageProps }) {
return (
<ThemeProvider theme={theme}>
<Provider options={{ clientMaxAge: 0, keepAlive: 0 }} session={pageProps.session}>
<Layout>
{/* Head */}
<Head>
<title>Kevin Support</title>
<link rel="icon" href="/static/favicon.png"/>
</Head>
{/* Page */}
<Component {...pageProps} />
</Layout>
</Provider>
</ThemeProvider>
)
}
We are using NextJS and Material-UI for our site, and upon loading the pages, it gives a FOUC. I've narrowed the problem down to the fact that the JS loads faster than the .css file, so I was wondering if there was a way to preload the .css file? All of our pages use the same .css file which is located under /pages/styles.css
Here is /pages/_app.js
if that's any help:
// pages/_app.js
import { Provider } from 'next-auth/client'
import { createMuiTheme } from '@material-ui/core/styles';
import { ThemeProvider } from '@material-ui/styles';
import styles from './styles.css'
import Layout from '../ponents/layout'
import Head from 'next/head'
const theme = createMuiTheme({
palette: {
primary: {
main: "#2196f3", // blue
},
secondary: {
main: "#d3d3d3", // gray
},
},
});
export default function _App ({ Component, pageProps }) {
return (
<ThemeProvider theme={theme}>
<Provider options={{ clientMaxAge: 0, keepAlive: 0 }} session={pageProps.session}>
<Layout>
{/* Head */}
<Head>
<title>Kevin Support</title>
<link rel="icon" href="/static/favicon.png"/>
</Head>
{/* Page */}
<Component {...pageProps} />
</Layout>
</Provider>
</ThemeProvider>
)
}
Share
Improve this question
asked Mar 11, 2021 at 17:45
alexover1alexover1
811 gold badge1 silver badge4 bronze badges
3
- Have you tried importing the styles directly from the node_modules? nextjs/docs/basic-features/… – Gh05d Commented Mar 11, 2021 at 21:26
- The styles are ing from a file I have called styles.css, not node_modules – alexover1 Commented Mar 11, 2021 at 22:40
- Does this stackoverflow./a/66089559/1870780 help answer your question? – juliomalves Commented Mar 13, 2021 at 12:41
4 Answers
Reset to default 2Perhaps styles weren't applied on the server-side. Try to add _document.js
from Material-UI's Next.js example. Adjust it to your needs.
// pages/_document.js
import React from 'react';
import Document, { Html, Head, Main, NextScript } from 'next/document';
import { ServerStyleSheets } from '@material-ui/core/styles';
import theme from '../src/theme';
export default class MyDocument extends Document {
render() {
return (
<Html lang="en">
<Head>
{/* PWA primary color */}
<meta name="theme-color" content={theme.palette.primary.main} />
<link
rel="stylesheet"
href="https://fonts.googleapis./css?family=Roboto:300,400,500,700&display=swap"
/>
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
// `getInitialProps` belongs to `_document` (instead of `_app`),
// it's patible with server-side generation (SSG).
MyDocument.getInitialProps = async (ctx) => {
// Resolution order
//
// On the server:
// 1. app.getInitialProps
// 2. page.getInitialProps
// 3. document.getInitialProps
// 4. app.render
// 5. page.render
// 6. document.render
//
// On the server with error:
// 1. document.getInitialProps
// 2. app.render
// 3. page.render
// 4. document.render
//
// On the client
// 1. app.getInitialProps
// 2. page.getInitialProps
// 3. app.render
// 4. page.render
// Render app and page and get the context of the page with collected side effects.
const sheets = new ServerStyleSheets();
const originalRenderPage = ctx.renderPage;
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: (App) => (props) => sheets.collect(<App {...props} />),
});
const initialProps = await Document.getInitialProps(ctx);
return {
...initialProps,
// Styles fragment is rendered after the app and page rendering finish.
styles: [...React.Children.toArray(initialProps.styles), sheets.getStyleElement()],
};
};
Also, you can try to remove server-side injected CSS in the _app.js
like so (see example):
React.useEffect(() => {
// Remove the server-side injected CSS.
const jssStyles = document.querySelector('#jss-server-side');
if (jssStyles) {
jssStyles.parentElement.removeChild(jssStyles);
}
}, []);
I faced this same issue. what I did was to make this work was to add this script inside _document.tsx
<script
dangerouslySetInnerHTML={{
__html: `
if(document) {
document.querySelectorAll("link[rel='preload'][as='style']").forEach(link => link.rel = "stylesheet")}
`
}}
/>
You could always use a display: none;
on the body element until the style sheet has loaded then display: block;
Load the CSS file with the <link>
element inside the head. The parsing process of the browser will then make sure that the CSS file is loaded before the site content is shown.
In your current approach you load the CSS is loaded with JavaScript, after the FCP has rendered the CSS will be parsed.
You have 2 options to fix this:
- You link the CSS file as mentioned above with a
<link>
element. - You get the text content of the CSS file and set it as the
innerHTML
of a<style>
element.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744407807a4572719.html
评论列表(0条)