问题定位
当接口返回的 JSON 体积过大(例如超过 1MB),首屏加载时间会显著增加。原因包括:网络传输耗时、客户端 JSON 解析耗时、以及可能的内存峰值。优化前,建议先通过浏览器开发者工具或抓包工具确认响应体大小和耗时分布。
字段裁剪:最直接的优化
原则:只返回客户端当前渲染所需的字段。
- 按场景拆分接口:列表页与详情页使用不同接口,列表页仅返回摘要字段(如 id、标题、缩略图)。
- 支持字段过滤:通过查询参数
fields=id,title,cover让客户端指定需要的字段,服务端动态投影。注意避免 SQL 注入,应使用白名单校验。 - 移除冗余嵌套:避免返回深层嵌套对象,尤其是与当前视图无关的关联数据。
示例:一个商品列表接口原本返回每个商品的完整详情(含描述、规格、评论),裁剪后仅返回 id、名称、价格、主图,体积可减少 70% 以上。
分页:控制单次数据量
分页是控制响应体积的经典手段,但需注意:
- 页码分页:使用
page和pageSize,适合数据量不大且跳页需求少的场景。 - 游标分页:使用
cursor(如上一页最后一条记录的 id 或时间戳),避免深分页性能问题,适合无限滚动。 - 合理设置每页大小:通常 20-50 条为宜,过大则失去分页意义,过小则请求频繁。
取舍:分页会增加请求次数,可能影响交互流畅度。对于首屏,可以只加载第一页数据,后续滚动加载。
流式响应:渐进式渲染
流式响应(如 HTTP 分块传输、SSE、JSON 流)允许服务端逐步发送数据,客户端边接收边渲染。
适用场景:
- 数据量极大且无法有效分页(如日志、导出)。
- 首屏需要尽快展示部分内容(如聊天记录、实时列表)。
实现要点:
- 服务端使用分块传输编码,逐条序列化并发送 JSON 对象(如每行一个 JSON,即 JSON Lines)。
- 客户端使用
fetch的response.body读取流,或使用EventSource处理 SSE。 - 注意错误处理:流中途出错需有重试或降级机制。
取舍:流式响应增加了前后端复杂度,且不利于缓存。若数据可静态缓存,优先考虑 CDN 缓存完整响应。
组合策略与决策建议
没有银弹,通常组合使用:
- 首屏优先:字段裁剪 + 分页,确保首屏请求轻量。
- 按需加载:非首屏数据延迟请求或流式加载。
- 监控与度量:持续监控接口响应大小和首屏时间,设定阈值告警。
决策树:
- 数据能否分页?能 → 分页 + 字段裁剪。
- 不能分页且首屏需快速展示?→ 流式响应 + 字段裁剪。
- 数据可缓存?→ 完整响应 + CDN 缓存。
总结
接口返回大 JSON 导致的首屏慢,本质是传输与解析成本问题。字段裁剪立竿见影,分页控制单次负载,流式响应提升感知速度。根据业务场景选择合适组合,并始终以度量数据驱动优化。