You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js 13中如何服务端渲染styled-components?解决样式滞后问题

Next.js 13 实现 styled-components 服务端渲染(解决样式滞后渲染问题)

Next.js 13 分为 App Router 和 Pages Router 两种路由模式,两者配置 styled-components 服务端渲染的方式略有不同,以下分别说明:

一、App Router 配置步骤

  1. 安装依赖
    安装核心包及 TypeScript 类型(TS 用户需装):

    npm install styled-components @types/styled-components
    # 或 yarn add styled-components @types/styled-components
    # 或 pnpm add styled-components @types/styled-components
    
  2. 配置根布局文件
    在 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>
      )
    }
    
  3. 配置 Next.js 编译选项
    在 next.config.js 中开启 SWC 对 styled-components 的支持,这是官方推荐的高性能方案:

    /** @type {import('next').NextConfig} */
    const nextConfig = {
      compiler: {
        styledComponents: true,
      },
    }
    
    module.exports = nextConfig
    

二、Pages Router 配置步骤

  1. 安装依赖
    同 App Router 的依赖安装步骤。

  2. 自定义 _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>
        )
      }
    }
    
  3. 配置 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 06:05:27