[英]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
orprops.dangerouslySetInnerHTML
.错误:只能设置
children
或props.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.