如何让NextJS组件仅在服务端渲染以减小客户端包体积?
如何让Next.js仅在服务端渲染组件,客户端只展示预渲染HTML?
需求说明
目标组件包含大量同步JavaScript计算逻辑,希望这些代码完全不进入客户端包,仅在服务端完成一次渲染,客户端只显示服务端生成的HTML,不执行该组件的任何客户端渲染逻辑。同时页面依赖URL动态参数(如配送状态页),无法通过全静态渲染实现。
已尝试无效方案
getServerSideProps:即便页面使用该方法,组件的JS代码仍会被打包发送到客户端,推测Next.js默认认为客户端可能需要重新渲染组件- 静态渲染:页面依赖动态URL参数,无法提前全量静态生成
- 基于
typeof window的条件渲染:无法实现"保留服务端渲染结果,同时客户端不执行组件渲染逻辑"的需求
可行解决方案
针对 Pages Router(Next.js 12及更早版本)
使用next/dynamic动态导入组件,明确指定仅在服务端渲染,避免组件代码被打包到客户端:
- 编写仅服务端运行的组件:
// 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>; }
- 在页面中动态导入该组件,设置
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),就会被视为服务端组件,代码完全不会进入客户端包:
- 编写服务端组件:
// 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>; }
- 在动态路由页面中直接导入使用:
// 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
相关产品推荐
相关产品推荐

