Nuxt 3 如何优化 useFetch 数据预取减少服务端请求次数

文章导读
Nuxt 3 优化 useFetch 减少服务端请求的核心是正确配置缓存 key 和利用 SSR 数据水合机制。适用于服务端渲染场景,风险在于配置错误会导致客户端重复请求或敏感数据暴露。
📋 目录
  1. 快速处理思路
  2. 为什么会这样
  3. 分步处理
  4. 怎么验证是否生效
  5. 常见坑
  6. 常见问题
  7. 参考来源
A A

Nuxt 3 优化 useFetch 减少服务端请求的核心是正确配置缓存 key 和利用 SSR 数据水合机制。适用于服务端渲染场景,风险在于配置错误会导致客户端重复请求或敏感数据暴露。

先说结论:通过设置唯一 key 和默认 SSR 行为避免重复请求,确保数据在服务端获取后客户端不再重发。

  • 先定位:确认重复请求发生在客户端导航还是组件重挂载场景
  • 先做:为 useFetch 设置唯一 key 选项并默认启用 server 端预取
  • 再验证:检查浏览器 Network 面板请求次数及页面源码__NUXT_DATA__

快速处理思路

不需要复杂命令,主要通过代码配置优化。在 useFetch 调用中显式添加 key 选项,确保同一请求在不同组件或导航中命中缓存。避免在组件顶层直接使用$fetch,改用 useFetch 或 useAsyncData 以获得 SSR 去重能力。对于自定义组合式函数,必须透传 key 选项以防止缓存失效。

为什么会这样

useFetch 内置去重逻辑,通过__NUXT_DATA__传递数据避免客户端重复请求。在服务端渲染场景中,Nuxt 会在服务端执行 useFetch 调用,将获取的数据直接注入到 HTML 中。客户端水合时,useFetch 会优先从这份内联数据中读取,而不会再次发起网络请求。若使用$fetch 或未配置 key,则无法利用此机制,导致服务端和客户端各请求一次。

分步处理

第一步是为每个 useFetch 请求设置唯一的 key 选项。key 用于标识请求缓存,若未设置或设置不当,Nuxt 无法识别相同请求,导致重复获取。示例代码:const { data } = useFetch('/api/products', { key: 'products-list' })

第二步是确认 server 和 lazy 选项配置。默认情况下 useFetch 会在服务端执行,若需控制执行时机可调整 lazy 选项。对于非关键数据,可设置lazy: true让客户端异步获取,但需注意这可能增加客户端请求次数。示例代码:useFetch('/api/config', { server: true, lazy: false })

第三步是优化自定义组合式函数实现。在封装 useApi 等函数时,必须确保 key 选项被正确传递到内部的 useFetch 调用中。若在封装层丢失 key,缓存机制将失效。示例代码:export function useApi(url) { return useFetch(url, { key: url }) }

Nuxt 3 如何优化 useFetch 数据预取减少服务端请求次数

怎么验证是否生效

首先检查浏览器 Network 面板,页面加载或导航时同一接口应只出现一次请求。若看到两次相同请求(一次 document 阶段,一次 xhr/fetch 阶段),说明水合失败或配置错误。其次查看页面源码,搜索__NUXT_DATA__,确认接口数据已内联在 HTML 中。若源码中无数据且 Network 有请求,说明未命中 SSR 缓存。

常见坑

自定义组合式函数未透传 key 选项导致缓存失效,这是最常见的重复请求原因。混用$fetch 和 useFetch,$fetch 不具备自动水合能力,在组件中直接使用会导致服务端和客户端各执行一次。敏感数据通过 useFetch 获取会内联在 HTML 中,可能暴露用户信息或密钥,此类数据建议改用客户端专属请求策略。

常见问题

能去除__NUXT_DATA__吗?

一般不能去除,它是 Nuxt 服务端数据水合的关键载体。若在 nuxt.config.ts 中设置experimental: { renderJsonPayloads: false },标签会消失但数据仍保留在 window.__NUXT__中。若完全不需要 SSR 数据预取,可配置ssr: false

useFetch 和$fetch 核心区别是什么?

useFetch 是 Nuxt 组合式函数,支持 SSR 数据复用和自动缓存;$fetch 是通用 HTTP 客户端,不具备自动水合机制。在组件内获取 SSR 数据应优先用 useFetch,脚本或非组件逻辑可用$fetch。

客户端导航时为什么还会重复请求?

因为页面组件被重新挂载导致组合式函数重新执行。可通过在布局组件中为<NuxtPage>添加 keepalive 属性保留页面状态,或在 useFetch 中确保 key 唯一且缓存未过期。

参考来源

  • Nuxt 3 中 useFetch 在客户端导航时重复请求的问题解析
  • Nuxt3 SSR 项目实战:如何优雅封装$fetch 和 useFetch 避免重复请求?
  • 避坑指南:Nuxt3 中 useFetch 和$fetch 的 7 个实战差异场景
  • Nuxt3:探索 useFetch 是如何做到避免客户端重复请求(GitHub Discussion)