怎样减少请求数?

访客 性能优化 2

本文目录导读:

  1. 前端策略(最常用,立竿见影)
  2. 后端策略(接口层)
  3. 网络与架构策略
  4. 架构级手段
  5. 总结与最佳实践清单

减少请求数是前端性能优化、后端服务优化以及网络优化的核心目标之一,请求数越少,意味着建立的 TCP 连接越少、DNS 查询越少、握手开销越小,页面加载速度会显著提升。

以下从前端策略后端策略网络策略架构策略四个维度,系统性地说明如何减少请求数。

前端策略(最常用,立竿见影)

资源合并与打包(Bundling)

  • CSS/JS 合并:将多个 CSS 文件合并为一个,多个 JS 文件合并为一个,使用 Webpack、Vite、Rollup 等打包工具。
  • 雪碧图(CSS Sprites):将多个小图标合并到一张大图上,通过 background-position 定位。注意:现在更推荐使用 SVG 图标或字体图标,它们只需一次请求。
  • 图片内联(Base64/Data URL):将非常小的图片(如 1x1 像素的透明图、小图标)转为 Base64 字符串直接写在 CSS/HTML 中,避免 HTTP 请求,通常只针对 2KB-10KB 以下的图片。

使用缓存策略(不是减少请求,而是减少无效请求)

  • 强缓存:通过设置 Cache-Control: max-age=31536000,让浏览器在有效期内完全不发请求。
  • 协商缓存:通过 ETagLast-Modified,当资源未变化时,服务器返回 304,不传输内容。

代码与资源优化

  • 图片懒加载:对于长列表页面,只加载可视区域的图片,其余图片用占位符替代。
  • 组件懒加载(Lazy Load):使用 React.lazy()import() 或 Vue 的异步组件,让首屏只加载必要的 JS 代码。
  • 无限滚动与虚拟列表:对于数万条数据,使用虚拟列表只渲染可见部分,而不是一次性请求所有数据。

减少外部资源与第三方库

  • 使用 CDN 的版本控制:如果使用 CDN 上的第三方库(如 jQuery、Lodash),尽量使用同一个 CDN 且版本固定。
  • 减少字体文件:只加载需要的字体子集,而不是整个字体包。
  • 移除不必要的库:例如用原生 JS 替代 jQuery,用 CSS 动画替代动画库。

后端策略(接口层)

API 合并与数据聚合(GraphQL/BFF)

  • GraphQL:客户端可以指定需要的数据字段,一次性获取多个关联资源的数据,避免多次 REST 请求。
  • BFF(Backend For Frontend):在前端和后端之间加一层中间层(如 Node.js),将多个微服务的接口聚合为一个接口返回。
  • 批量接口(Batch API):提供一个 /batch 接口,允许客户端在请求体中传入多个 API 的调用参数,后台统一处理并返回。

避免“瀑布流”请求

  • 使用 Promise.all 并发请求,而不是串行等待(虽然不减少请求数,但减少等待时间)。
  • 后端提供一次性返回关联数据的接口(请求用户信息时,直接返回用户所属团队最近订单的列表,而不是前端再发两次请求)。

使用 WebSocket 替代轮询

  • 对于实时更新的场景(如聊天、通知、价格变化),不要使用 setInterval 定时发 HTTP 请求去轮询。
  • 使用 WebSocketServer-Sent Events (SSE) 建立长连接,服务器主动推送数据,只建立一次连接。

网络与架构策略

HTTP/2 多路复用(不是严格减少请求,但节省连接)

  • HTTP/2 支持多路复用,可以在一个 TCP 连接上并行发送多个请求和响应,虽然请求数没变,但消除了队头阻塞,减少了 TCP 连接建立的开销。
  • 注意:如果用了 HTTP/2,就不要强行合并 CSS/JS 了(反而会影响缓存粒度),可以适当拆分为更小粒度的文件,利用缓存优势。

使用 CDN

  • 将静态资源部署到 CDN 节点,用户从最近的节点获取资源,请求数不变,但请求的距离和时间大大缩短。
  • CDN 还可以做预解析,提前解析 DNS。

预加载与预连接

  • <link rel="preload">:提前加载关键资源(如字体、首屏图片、关键 CSS)。
  • <link rel="preconnect">:提前与第三方服务器(如 Google Fonts、CDN)建立 TCP 连接,减少后续请求的握手时间。
  • <link rel="dns-prefetch">:提前完成 DNS 域名解析。

架构级手段

服务端渲染(SSR)或静态站点生成(SSG)

  • SSR:在服务端渲染好 HTML 返回,客户端不需要发 Ajax 请求去获取初始数据,首屏请求数从“1个HTML + 多个API请求”减少为“1个HTML”。
  • SSG:构建时生成所有 HTML 页面,访问时直接返回静态文件,无需调用后端服务。

采用微前端或微服务架构治理

  • 将不同业务模块拆分成独立部署的子应用,但通过统一的调度层,按需加载子应用的代码,避免加载整个 SPA 应用的所有代码。

总结与最佳实践清单

场景 建议手段 效果
静态资源(JS/CSS/图片) 合并、雪碧图、Base64 内联、使用 CDN + 强缓存 减少大量 HTTP 连接
首屏数据 SSR / SSG / 后端聚合 / GraphQL 从 N 次请求变为 1 次
多个小接口 合并为一个批量接口 / BFF 层 减少多次往返
实时数据 WebSocket / SSE 从定时轮询变为一次连接
重复请求 设置合理的 Cache-Control / ETag 浏览器不发请求(304)
列表/长页 懒加载、虚拟滚动、无限滚动 减少非可视区域请求

核心思路能缓存就不请求,能合并就不拆分,能推流就不轮询,能内联就不外链。 在实际项目中,建议结合性能监控工具(如 Chrome DevTools 的 Network 面板、Lighthouse)分析请求瀑布图,找到最耗时的“长尾请求”和“串联请求”,针对性解决。

标签: 减少请求数 请求合并

抱歉,评论功能暂时关闭!