【问题标题】:Universal rendering creates a delay between DOMContentLoaded event to Load event通用渲染在 DOMContentLoaded 事件和 Load 事件之间产生延迟
【发布时间】:2017-08-06 01:00:35
【问题描述】:

我对样式化组件感到非常兴奋,如果不是因为这个,我很想使用它...
我已经准备了两个使用 next.js 通用渲染库的示例项目。
第一个示例使用 styled-components 作为解决方案,第二个示例使用他们的默认 CSS 解决方案 styled-jsx。
这两个示例都包含完全相同的代码,但复杂性最低。 正如您很快就会看到的那样——在 styled-components 示例中,在 DOMContentLoaded 事件和 Load 事件之间存在令人不安的延迟,其中用户实际上看到了未设置样式的 html 标记,而在使用 styled-jsx 的第二个示例中,这不是案例。

两个演示现在都使用 Zeit 在线托管:
1 - https://01-styled-components-sqprkdqeft.now.sh
2 - https://02-styled-jsx-nhrynpsdox.now.sh

github 上提供的源代码:
1 - https://github.com/Ajar-Ajar/next-demo--styled-components
2 - https://github.com/Ajar-Ajar/next-demo--styled-jsx

我非常感谢任何关于为什么它发生在一个而不是另一个的见解, 当然还有任何修改这种行为的方法,因为我喜欢使用 styled-components 的许多特性和优势。

谢谢
半开
:)

【问题讨论】:

    标签: css reactjs styled-components next.js universal-react


    【解决方案1】:

    这里缺少的是服务器上的样式注入。基本上,当您在 JavaScript 中编写样式时,您必须在服务器上获取生成的样式并将它们作为 style 标记注入到生成的 HTML 中。

    Next 的内置解决方案会自动为您执行此操作,使用styled-components,您必须做一点手动工作并添加一个如下所示的pages/_document.js 文件:

    import Document, { Head, Main, NextScript } from 'next/document'
    import { styleSheet } from 'styled-components'
    
    export default class MyDocument extends Document {
      static async getInitialProps ({ renderPage }) {
        const page = renderPage()
        const styles = (
          <style dangerouslySetInnerHTML={{ __html: styleSheet.rules().map(rule => rule.cssText).join('\n') }} />
        )
        return { ...page, styles }
      }
    
      render () {
        return (
          <html>
            <Head>
              <title>My page</title>
            </Head>
            <body>
              <Main />
              <NextScript />
            </body>
          </html>
        )
      }
    }
    

    请注意我们如何使用来自styled-components 的样式注入样式标签。这就是它的全部内容,现在那些没有样式的内容已经消失了! ?(取自the official example


    注意:使用 v2 of styled-components(即将推出,您现在可以使用 `npm i --save styled-components@next 获取它)会有 官方SSR 的 API 所以看起来更像这样:

    import Document, { Head, Main, NextScript } from 'next/document'
    import styleSheet from 'styled-components/lib/models/StyleSheet'
    
    export default class MyDocument extends Document {
      static async getInitialProps ({ renderPage }) {
        const page = renderPage()
        const styles = (
          <style dangerouslySetInnerHTML={{ __html: styleSheet.getCSS() }} />
        )
        return { ...page, styles }
      }
    
      render () {
        return (
          <html>
            <Head>
              <title>My page</title>
            </Head>
            <body>
              <Main />
              <NextScript />
            </body>
          </html>
        )
      }
    }
    

    希望有帮助!

    【讨论】:

      【解决方案2】:

      以下是使用带有 next 的 styled-components 来避免该问题的推荐方法: https://github.com/vercel/next.js/blob/master/examples/with-styled-components/pages/_document.js

      import Document from 'next/document'
      import { ServerStyleSheet } from 'styled-components'
      
      export default class MyDocument extends Document {
        static async getInitialProps(ctx) {
          const sheet = new ServerStyleSheet()
          const originalRenderPage = ctx.renderPage
      
      try {
        ctx.renderPage = () =>
          originalRenderPage({
            enhanceApp: (App) => (props) =>
              sheet.collectStyles(<App {...props} />),
          })
      
        const initialProps = await Document.getInitialProps(ctx)
        return {
          ...initialProps,
          styles: (
            <>
              {initialProps.styles}
              {sheet.getStyleElement()}
            </>
          ),
        }
      } finally {
        sheet.seal()
      }
      render () {
      return (
        <html>
          <Head>
            <title>My page</title>
          </Head>
          <body>
            <Main />
            <NextScript />
          </body>
        </html>
      )
      
       }
      }
      

      【讨论】:

        猜你喜欢
        • 2013-09-20
        • 2015-05-16
        • 2017-08-14
        • 1970-01-01
        • 1970-01-01
        • 2021-06-26
        • 2012-11-05
        • 2014-02-07
        相关资源
        最近更新 更多