2.1 KiB
2.1 KiB
title, impact, impactDescription, tags
| title | impact | impactDescription | tags |
|---|---|---|---|
| Avoid Duplicate Serialization in RSC Props | LOW | reduces network payload by avoiding duplicate serialization | server, rsc, serialization, props, client-components |
在 RSC Props 中避免重复序列化
影响程度:LOW(通过避免重复序列化减少网络负载)
RSC→client 序列化按对象引用去重,而非按值去重。相同引用 = 序列化一次;新引用 = 再次序列化。将转换操作(.toSorted()、.filter()、.map())放在客户端执行,而不是服务端。
错误做法(数组重复):
// RSC:发送 6 个字符串(2 个数组 × 3 个元素)
<ClientList usernames={usernames} usernamesOrdered={usernames.toSorted()} />
正确做法(发送 3 个字符串):
// RSC:只发送一次
<ClientList usernames={usernames} />
// 客户端:在客户端进行转换
'use client'
const sorted = useMemo(() => [...usernames].sort(), [usernames])
嵌套去重行为:
去重是递归进行的。影响程度因数据类型而异:
string[]、number[]、boolean[]:HIGH 影响 - 数组及所有基本类型值完全重复object[]:LOW 影响 - 数组结构重复,但嵌套对象按引用去重
// string[] - 全部重复
usernames={['a','b']} sorted={usernames.toSorted()} // 发送 4 个字符串
// object[] - 仅数组结构重复
users={[{id:1},{id:2}]} sorted={users.toSorted()} // 发送 2 个数组 + 2 个唯一对象(而非 4 个)
破坏去重的操作(创建新引用):
- 数组:
.toSorted()、.filter()、.map()、.slice()、[...arr] - 对象:
{...obj}、Object.assign()、structuredClone()、JSON.parse(JSON.stringify())
更多示例:
// ❌ 错误做法
<C users={users} active={users.filter(u => u.active)} />
<C product={product} productName={product.name} />
// ✅ 正确做法
<C users={users} />
<C product={product} />
// 在客户端进行过滤/解构
例外情况: 当转换操作开销较大,或者客户端不需要原始数据时,可以传递派生数据。