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

如何让NextJS组件仅在服务端渲染以减小客户端包体积?

如何让Next.js仅在服务端渲染组件,客户端只展示预渲染HTML?

需求说明

目标组件包含大量同步JavaScript计算逻辑,希望这些代码完全不进入客户端包,仅在服务端完成一次渲染,客户端只显示服务端生成的HTML,不执行该组件的任何客户端渲染逻辑。同时页面依赖URL动态参数(如配送状态页),无法通过全静态渲染实现。

已尝试无效方案

  • getServerSideProps:即便页面使用该方法,组件的JS代码仍会被打包发送到客户端,推测Next.js默认认为客户端可能需要重新渲染组件
  • 静态渲染:页面依赖动态URL参数,无法提前全量静态生成
  • 基于typeof window的条件渲染:无法实现"保留服务端渲染结果,同时客户端不执行组件渲染逻辑"的需求

可行解决方案

针对 Pages Router(Next.js 12及更早版本)

使用next/dynamic动态导入组件,明确指定仅在服务端渲染,避免组件代码被打包到客户端:

  1. 编写仅服务端运行的组件:
// components/HeavyServerComponent.js
export default function HeavyServerComponent() {
  // 这里放置你的大量同步计算逻辑
  const heavyCalculationResult = (() => {
    // 示例:模拟重计算
    let result = 0;
    for (let i = 0; i < 1000000; i++) {
      result += i;
    }
    return result;
  })();

  return <div>计算结果:{heavyCalculationResult}</div>;
}
  1. 在页面中动态导入该组件,设置ssr: true:
// pages/delivery/[id].js
import dynamic from 'next/dynamic';

// 仅在服务端渲染,不打包到客户端
const HeavyComponent = dynamic(() => import('../../components/HeavyServerComponent'), {
  ssr: true,
  // 服务端渲染完成前的客户端占位(可选)
  loading: () => <div>加载中...</div>,
});

export default function DeliveryStatusPage({ params }) {
  return (
    <div>
      <h1>配送状态 #{params.id}</h1>
      <HeavyComponent />
    </div>
  );
}

export async function getServerSideProps(context) {
  return {
    props: {
      params: { id: context.params.id },
    },
  };
}

这样配置后,HeavyServerComponent的代码只会在服务端执行,客户端收到的只有预渲染好的HTML,不会加载该组件的JS代码。

针对 App Router(Next.js 13+)

App Router默认支持服务端组件,无需额外配置,只要组件不使用客户端专属API(如window、document),就会被视为服务端组件,代码完全不会进入客户端包:

  1. 编写服务端组件:
// app/components/HeavyServerComponent.jsx
export default function HeavyServerComponent() {
  // 大量同步计算逻辑
  const heavyCalculationResult = (() => {
    let result = 0;
    for (let i = 0; i < 1000000; i++) {
      result += i;
    }
    return result;
  })();

  return <div>计算结果:{heavyCalculationResult}</div>;
}
  1. 在动态路由页面中直接导入使用:
// app/delivery/[id]/page.jsx
import HeavyServerComponent from '../../components/HeavyServerComponent';

export default function DeliveryStatusPage({ params }) {
  return (
    <div>
      <h1>配送状态 #{params.id}</h1>
      <HeavyServerComponent />
    </div>
  );
}

服务端组件会在服务端完成渲染,客户端仅收到生成的HTML,不会执行组件的任何JS代码,完美匹配需求。


内容的提问来源于stack exchange,提问作者Null

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 20:45:26