[英]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. 我想要的是在標簽下的 _document.js 標簽中加載關鍵 css 后,加載不高於首屏的非關鍵 css。
_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>
</>
)
}
}
正如@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;
在您的組件中,您可以放置 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} />; };
我從當前的 repo 中得到了這段代碼的源代碼:
https://github.com/JamieMason/nextjs-typescript-tailwind-critical-css
看看這里
這是我目前最喜歡的解決方案,來自這里: https://github.com/facebook/react/issues/12014#issuecomment-434534770
它會在您的腦海中產生兩個空的<script></script>
標簽,但可以。
<script
dangerouslySetInnerHTML={{
__html: `</script><link rel='preload' href='style.css' as='style' onload="this.onload=null;this.rel='stylesheet'"/><script>`,
}}
/>
Next.js 團隊表示他們的組件可以采用類似的策略,但在實踐中,我遇到了編譯錯誤: https://github.com/vercel/next.js/issues/8478#issuecomment-524332188
我收到的錯誤是:
錯誤:只能設置
children
或props.dangerouslySetInnerHTML
。
根據文檔,可能必須將<Head>
移動到 _document.js 而不是 _app.js 中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.