vercel / next.js

The React Framework
https://nextjs.org
MIT License
126.86k stars 26.97k forks source link

Best practice for preloading screen #5736

Closed WebDeg-Brian closed 5 years ago

WebDeg-Brian commented 5 years ago

I have my preloader screen working, but I'm not sure whether this is a best practice. My code:

Note: The main code and stylings are in _document.js

_document.js

export default class extends Document {
 //...other stuffs up here
  render() {
    const { 
      pageContext,
      styleTag
    } = this.props;

    return (
      <html lang="en" dir="ltr">
        <Head>
          <meta charSet="utf-8" />
          <meta
            name="viewport"
            content="minimum-scale=1, initial-scale=1, width=device-width, shrink-to-fit=no"
          />
          <meta name="theme-color" content={pageContext.theme.palette.primary.main} />
          <link
            rel="stylesheet"
            href="https://fonts.googleapis.com/css?family=Roboto:300,400,500"
          />
          <link
            rel="stylesheet"
            href="/static/css/nprogress.css"
          />
          {styleTag}
        </Head>
        <body>
          <style global jsx>
            {`
              .eagle-loading {
                position: fixed;
                width: 100%;
                height: 100%;
                background: ${pageContext.theme.palette.primary.main} url(/static/images/logo.png) center no-repeat;
                z-index: 1700;
              }
              .eagle-loading.eagle-loaded {
                transition: opacity 0.6s;
                opacity: 0;
              }

              .eagle-loading-wrapper {
                display: flex;
                width: 100%;
                position: absolute;
                bottom: 5%;
              }

              .eagle-loading-ring {
                display: inline-block;
                width: 64px;
                height: 64px;
                margin: auto;
              }
              .eagle-loading-ring:after {
                content: '';
                display: block;
                width: 46px;
                height: 46px;
                margin: 1px;
                border-radius: 50%;
                border: 2px solid #fff;
                border-color: #fff transparent #fff transparent;
                animation: eagle-spinning 1.2s linear infinite;
              }

              @keyframes eagle-spinning {
                0% {
                  transform: rotate(0deg);
                }
                100% {
                  transform: rotate(360deg);
                }
              }

            `}
          </style>
          <div class="eagle-loading">
            <div class="eagle-loading-wrapper">
              <div class="eagle-loading-ring" />
            </div>
          </div>
          <Main />
          <NextScript />
        </body>
      </html>
    );
  }
}

_app.js

export default withRedux(connect(null, rootActions)(class SiteApp extends App {
  pageContext = getPageContext();

  componentDidMount() {
    const jssStyles = document.querySelector('#Mui-SSR'),
    preloaderScreen = document.querySelector('.eagle-loading');

    if (preloaderScreen) preloaderScreen.classList.add('eagle-loaded');

    if (jssStyles && jssStyles.parentNode) {
      jssStyles.parentNode.removeChild(jssStyles);
    }
  }

  render() {
    const { 
      Component, 
      pageProps,
      store
    } = this.props, {
      theme,
      sheetsRegistry,
      sheetsManager,
      generateClassName
    } = this.pageContext

    return (
      <Container>
        <Provider store={store}>
          <JssProvider
            registry={sheetsRegistry}
            generateClassName={generateClassName}
          >
            <MuiThemeProvider
              theme={theme}
              sheetsManager={sheetsManager}
            >
              <CssBaseline />
              <Navigation />
              <Component 
                pageContext={this.pageContext}
                {...pageProps} 
              />
            </MuiThemeProvider>
          </JssProvider>
        </Provider>
      </Container>
    );
  }
}))

Any help is appreciated. Thank in advance

WebDeg-Brian commented 5 years ago

Nevermind, I got it. For those who has the same question is probably better to put it in _app.js

huykon commented 5 years ago

can you share preloading code?