iT邦幫忙

0

Vue的套件@tanstack/vue-query要如何避免Server及Client端重複發送API

vue
  • 分享至 

  • xImage

目前小弟接手一個專案,前端Vue都是利用@tanstack/vue-query的套件來向後端發送API,只是這樣要如何避免Server及Client端重複發送API?
我有將問題丟給Copilot,他給出的解答如下:

Vue Query 的快取機制能有效避免伺服器和客戶端重複呼叫 API,主要是通過以下幾個方面來實現的:

  1. 快取資料
    當你使用 useQuery 來獲取資料時,Vue Query 會自動將返回的資料快取起來。這意味著在相同的查詢鍵(queryKey)下,後續的查詢會直接從快取中獲取資料,而不是重新發送 API 請求1。

  2. 資料過期時間(staleTime)
    你可以設定資料的過期時間(staleTime),在這段時間內,資料被認為是新鮮的,不會重新獲取。這樣可以避免在短時間內重複發送相同的 API 請求1。

const { data } = useQuery('todos', fetchTodos, {
staleTime: 1000 * 60 * 5, // 資料過期時間設為5分鐘
})
3. 初始資料(initialData)
在伺服器端渲染(SSR)中,你可以使用 initialData 來提供初始資料,這樣客戶端在初次渲染時就不需要再次發送 API 請求1。

const { data } = useQuery('todos', fetchTodos, {
initialData: serverData, // 來自伺服器端的初始資料
})
4. 快取鍵(queryKey)
每個查詢都有一個唯一的快取鍵(queryKey),這個鍵用來標識和管理快取資料。當相同的快取鍵被使用時,Vue Query 會重用快取中的資料,而不是重新發送請求1。

  1. 背景重新獲取(Background Refetching)
    當資料過期或需要更新時,Vue Query 會在背景中自動重新獲取資料,而不會影響使用者的體驗。這樣可以確保使用者看到的是最新的資料,同時避免不必要的重複請求1。

綜合範例
以下是一個綜合範例,展示如何利用 Vue Query 的快取機制來避免重複呼叫 API:

import { useQuery } from '@tanstack/vue-query'

export default {
setup() {
const { data, error, isLoading } = useQuery(
'todos',
() => fetch('/api/todos').then(res => res.json()),
{
staleTime: 1000 * 60 * 5, // 資料過期時間設為5分鐘
initialData: serverData, // 來自伺服器端的初始資料
}
)

return { data, error, isLoading }

}
}
在這個範例中,useQuery 會快取從 /api/todos 獲取的資料,並在5分鐘內重用這些資料,避免重複請求。同時,利用 initialData 提供伺服器端的初始資料,避免客戶端初次渲染時重複發送 API 請求。

然而,我看官網的快取範例說明(https://tanstack.com/query/latest/docs/framework/vue/guides/caching),似乎只有設定 staleTime (資料過期時間),在時間範圍內前端才不會重複發送API請求。

因此,到底是Vue Query本身的快取機制,還是只有staleTime,抑或是其他的機制可以避免Server及Client端重複發送API?

圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 個回答

1
呆呆小將
iT邦新手 2 級 ‧ 2025-02-27 16:40:47

看要不要檢查一下,有時候是原先的工程師沒有善用套件不是套件問題

  1. api useQuery 是否反覆被初始化,甚至你畫面包含 api 整組被重新 render 出來那就會是整組新的
  2. 是否原先的使用者是無條件使用 refetch 呼叫,又或者只要打 api 就會先把 queryKey 更動,導致每次都會搜尋新的內容

以上是前陣子初次用時踩的雷,搞不好會中,不然更多的就要看 Code 了

了解,所以只要api的queryKey沒有更動,就不會重新發送api請求嗎?

我要發表回答

立即登入回答