SSR 应用中的路由预取和页面切换性能如何优化?
简化版
SSR 首屏靠服务端 HTML 提升加载体验,但用户进入站内后,页面切换仍要关注路由预取、数据预取、代码分包和缓存复用。常见优化包括链接进入视口时预取、鼠标悬停时预取、只预取高概率路由、复用已经请求的数据、避免预取个性化敏感数据。预取的目标是缩短下一跳等待,但不能把带宽、服务端渲染和接口压力打满。
详细版
SSR 应用不是每次点击都必须完整刷新页面。很多框架会在首屏 SSR 后接管为客户端路由,后续切换可以按需加载页面 JS、数据和 RSC payload。
预取可以让下一页更快,但也有成本:移动网络浪费流量,低端机增加解析压力,服务端可能被无效预取请求放大。好的策略应该按页面重要性、用户行为概率、网络状态和设备能力动态控制。
面试时要强调“预取是概率优化,不是越多越好”。
完整版教学
一、SSR 页面切换的两种模式
一种是传统多页刷新,每次点击都重新请求 HTML。
另一种是首屏 SSR,后续由客户端路由接管。
现代 SSR 框架常采用第二种模式,以兼顾首屏和站内体验。
这时路由切换性能取决于代码、数据和缓存。
二、预取对象有哪些
| 对象 | 示例 | 成本 |
|---|---|---|
| 路由代码 | 下一页 JS chunk | 下载和解析成本 |
| 页面数据 | 列表详情数据 | 接口和缓存成本 |
| HTML / Payload | SSR 或 RSC 结果 | 服务端渲染成本 |
| 图片资源 | 首屏图片 | 带宽成本 |
不是所有资源都应该同时预取。
三、触发时机
链接进入视口时可以低优先级预取。
用户 hover 或 touchstart 时可以更积极预取。
搜索结果、推荐列表这类高概率点击项更适合预取。
分页末尾、深层低概率链接可以不预取。
弱网、流量节省模式、低电量环境应减少预取。
四、代码示例
function shouldPrefetch(link, context) {
if (context.saveData) return false;
if (context.effectiveType === "2g") return false;
if (link.dataset.priority === "high") return true;
return link.isInViewport && context.idle;
}
真实框架通常已有默认预取策略,但团队仍要知道如何关闭或调整。
五、服务端压力控制
预取请求也是真请求。
如果大量用户打开首页就预取所有详情页,SSR 服务会被放大。
可以只预取静态 chunk,不预取动态 HTML。
也可以对预取请求使用低优先级、短超时、缓存命中优先。
预取优化的是下一跳体验,但它消耗的是当前页面的带宽和服务端预算。
六、数据一致性
预取的数据可能在用户点击前已经变旧。
价格、库存、权限这类数据点击后仍要校验。
预取结果可以作为初始展示,但关键操作前必须重新确认。
缓存时间越长,越要标明数据新鲜度。
七、误区和追问
- 误区:SSR 应用不需要路由优化。 SSR 只解决首屏,站内切换仍可能慢。
- 误区:预取越多页面越快。 预取过多会浪费带宽、占用主线程、增加服务端压力。
- 误区:预取数据可以直接用于关键交易。 关键数据仍要在操作时重新校验。
- 追问:怎么判断哪些链接要预取? 看点击概率、页面价值、网络状态、设备能力和资源成本。
- 追问:预取导致接口压力大怎么办? 限制范围、降低优先级、只预取代码、依赖 CDN 缓存或服务端限流。
- 追问:移动端要不要默认预取? 要更谨慎,尤其关注 Save-Data、弱网和流量成本。
八、面试收束
回答时可以从“首屏 SSR、站内路由、预取策略、成本控制、数据新鲜度”五步讲。
这样能体现你理解 SSR 应用的性能不是只看首屏 HTML。