Next.js 13中如何服务端渲染styled-components?解决样式滞后问题
Next.js 13 实现 styled-components 服务端渲染(解决样式滞后渲染问题)
Next.js 13 分为 App Router 和 Pages Router 两种路由模式,两者配置 styled-components 服务端渲染的方式略有不同,以下分别说明:
一、App Router 配置步骤
安装依赖
安装核心包及 TypeScript 类型(TS 用户需装):npm install styled-components @types/styled-components # 或 yarn add styled-components @types/styled-components # 或 pnpm add styled-components @types/styled-components配置根布局文件
在app/layout.tsx(JS 项目用layout.jsx)中,通过ServerStyleSheet收集服务端样式并注入到 HTML 头部:import { ServerStyleSheet, StyleSheetManager } from 'styled-components' import type { Metadata } from 'next' export const metadata: Metadata = { title: 'Styled Components SSR', description: 'Next.js 13 App Router 集成 styled-components 服务端渲染', } export default function RootLayout({ children }: { children: React.ReactNode }) { const sheet = new ServerStyleSheet() const styledChildren = sheet.collectStyles(children) const styles = sheet.getStyleElement() return ( <html lang="zh-CN"> <head>{styles}</head> <body> <StyleSheetManager sheet={sheet.instance}> {styledChildren} </StyleSheetManager> </body> </html> ) }配置 Next.js 编译选项
在next.config.js中开启 SWC 对 styled-components 的支持,这是官方推荐的高性能方案:/** @type {import('next').NextConfig} */ const nextConfig = { compiler: { styledComponents: true, }, } module.exports = nextConfig
二、Pages Router 配置步骤
安装依赖
同 App Router 的依赖安装步骤。自定义 _document 文件
在pages/_document.tsx(JS 项目用_document.jsx)中重写getInitialProps,实现服务端样式收集:import Document, { DocumentContext, Head, Html, Main, NextScript } from 'next/document' import { ServerStyleSheet } from 'styled-components' export default class MyDocument extends Document { static async getInitialProps(ctx: DocumentContext) { 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 lang="zh-CN"> <Head /> <body> <Main /> <NextScript /> </body> </Html> ) } }配置 Next.js 编译选项
同 App Router 的next.config.js配置,开启 styled-components 编译支持。
三、解决组件先于样式渲染的问题
上述配置的核心逻辑是在服务端提前生成所有 styled-components 的样式,并将其作为 <style> 标签注入到 HTML 的 <head> 中。这样客户端首次加载页面时,HTML 已经包含完整的样式规则,组件渲染时就能直接应用样式,从根源上避免了“组件先渲染、样式后加载”的闪屏或滞后问题。
额外注意事项:
- 避免在客户端动态创建样式(如在
useEffect之外的客户端逻辑中生成新的 styled 组件),这类样式无法被服务端收集,仍可能导致滞后。 - TypeScript 用户需确保
@types/styled-components版本与styled-components核心包版本匹配,避免类型报错。 - 不要同时使用
babel-plugin-styled-components和 Next.js 的 SWC 编译选项,优先使用 SWC 方案以获得更好的性能。
内容的提问来源于stack exchange,提问作者Kauan
相关产品推荐
相关产品推荐

