简体   繁体   English

如何在 next.js 中延迟加载渲染阻塞 css?

[英]How to defer load render blocking css in next.js?

As you can see in the below next.js code I am trying to defer load the render blocking css by giving my main.css file path in href attribute but I am struggling to do it in next.js. As you can see in the below next.js code I am trying to defer load the render blocking css by giving my main.css file path in href attribute but I am struggling to do it in next.js. What I want is after loading the critical css in _document.js tag under tag, to load the non-critical css which is not above the fold.我想要的是在标签下的 _document.js 标签中加载关键 css 后,加载不高于首屏的非关键 css。

_app.js _app.js

import App from "next/app"
import Head from "next/head"
import React from "react"
import { observer, Provider } from 'mobx-react'
import Layout from "../components/Layout"
import allStores from '../store'

export default class MyApp extends App {
componentDidMount = () => {
       
};
render() {
        const { Component, pageProps, header, footer,  } = this.props
        return (
            <>
                <Head >
                    <link rel="preload" href="path/to/main.css" as="style" 
                    onLoad="this.onload=null;this.rel='stylesheet'"></link>
                </Head>
                <Provider {...allStores}>
                    <Layout header={header}  footer={footer}>
                        <Component {...pageProps} />
                    </Layout>
                </Provider>
            </>
        )
    }
}

as @chrishrtmn said at _document.js you can do like this:正如@chrishrtmn 在 _document.js 所说,你可以这样做:

 import Document, { Main, NextScript } from 'next/document'; import { CriticalCss } from '../components/CriticalCss'; class NextDocument extends Document { render() { return ( <html> <CriticalCssHead /> <body> <Main /> <NextScript /> </body> </html> ); } } export default NextDocument;

as in your component you can put the CSS:在您的组件中,您可以放置 CSS:

 import { readFileSync } from 'fs'; import { join } from 'path'; export interface Props { assetPrefix?: string; file: string; nonce?: string; } export const InlineStyle: React.FC<Props> = ({ assetPrefix, file, nonce }) => { const cssPath = join(process.cwd(), '.next', file); const cssSource = readFileSync(cssPath, 'utf-8'); const html = { __html: cssSource }; const id = `${assetPrefix}/_next/${file}`; return <style dangerouslySetInnerHTML={html} data-href={id} nonce={nonce} />; };

I got the source for this code from the current repo:我从当前的 repo 中得到了这段代码的源代码:

https://github.com/JamieMason/nextjs-typescript-tailwind-critical-css https://github.com/JamieMason/nextjs-typescript-tailwind-critical-css

have a look here看看这里

https://github.com/JamieMason/nextjs-typescript-tailwind-critical-css/tree/master/components/CriticalCssHead https://github.com/JamieMason/nextjs-typescript-tailwind-critical-css/tree/master/components/CriticalCssHead

Here's my current favorite solution, sourced from here: https://github.com/facebook/react/issues/12014#issuecomment-434534770这是我目前最喜欢的解决方案,来自这里: https://github.com/facebook/react/issues/12014#issuecomment-434534770

It results in two empty <script></script> tags in your head, but works.它会在您的脑海中产生两个空的<script></script>标签,但可以。

<script
  dangerouslySetInnerHTML={{
    __html: `</script><link rel='preload' href='style.css' as='style' onload="this.onload=null;this.rel='stylesheet'"/><script>`,
  }}
/>

The Next.js team indicated that a similar strategy is possible with their component, but in practice, I was getting compilation errors: https://github.com/vercel/next.js/issues/8478#issuecomment-524332188 Next.js 团队表示他们的组件可以采用类似的策略,但在实践中,我遇到了编译错误: https://github.com/vercel/next.js/issues/8478#issuecomment-524332188

The error I received was:我收到的错误是:

Error: Can only set one of children or props.dangerouslySetInnerHTML .错误:只能设置childrenprops.dangerouslySetInnerHTML

Might have to move the <Head> into _document.js instead of _app.js according to the documentation.根据文档,可能必须将<Head>移动到 _document.js 而不是 _app.js 中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM