我正在使用 apollo-client、apollo-link 和 react-apollo,想要完全禁用缓存,但不知道如何操作。
我阅读了 apollo-cache-inmemory
的源代码,它在构造函数中有一个 config
参数,但我无法建立一个虚拟的 storeFactory
来使其工作。
我正在使用 apollo-client、apollo-link 和 react-apollo,想要完全禁用缓存,但不知道如何操作。
我阅读了 apollo-cache-inmemory
的源代码,它在构造函数中有一个 config
参数,但我无法建立一个虚拟的 storeFactory
来使其工作。
defaultOptions
:const defaultOptions: DefaultOptions = {
watchQuery: {
fetchPolicy: 'no-cache',
errorPolicy: 'ignore',
},
query: {
fetchPolicy: 'no-cache',
errorPolicy: 'all',
},
}
const client = new ApolloClient({
link: concat(authMiddleware, httpLink),
cache: new InMemoryCache(),
defaultOptions: defaultOptions,
});
fetchPolicy
作为 no-cache
,避免使用缓存。
请参阅 https://www.apollographql.com/docs/react/api/core/ApolloClient/#defaultoptions
实际上,将fetchPolicy
设置为network-only
仍会将响应保存到缓存中以供稍后使用,跳过读取并强制进行网络请求。
如果您真的想禁用缓存,包括读取和写入,请使用no-cache
。这与network-only
类似,但是查询结果不会存储在缓存中,即"除了查询结果不会存储在缓存中外,与network-only相似。"
请查看官方文档:https://www.apollographql.com/docs/react/data/queries/#configuring-fetch-logic
我建议不要禁用Apollo客户端的内置缓存功能。相反,您可以针对每个查询始终设置fetchPolicy: 'network-only'
,例如:
我建议不要禁用Apollo客户端的内置缓存功能。相反,您可以针对每个查询始终设置fetchPolicy: 'network-only'
。
<Query
query={GET_DOG_PHOTO}
variables={{ breed }}
fetchPolicy='network-only'
>
{({ loading, error, data, refetch, networkStatus }) => {
...
}}
</Query>
使用此查询获取数据时,它总是首先进行网络请求而不是从缓存中读取。
Irvin Chan的答案可以禁用Apollo的缓存行为,但通过性能分析我发现它实际上并没有完全禁用它。在幕后,它仍然向缓存添加内容,只是缓存未被使用而已。
这在我的情况下是一个问题,因为缓存行为本身会对我的应用程序产生明显的性能影响。(在大约20秒的重载数据期间需要处理约1秒的额外开销,即浪费了约5%的CPU时间)
为了解决这个问题,我创建了这个空的InMemoryCache
备选项:
import {ApolloCache, NormalizedCacheObject} from "web-vcore/nm/@apollo/client.js";
const emptyCacheObj = {};
export class VoidCache extends ApolloCache<NormalizedCacheObject> {
read(options) { return null; }
write(options) { return undefined; }
diff(options) { return {}; }
watch(watch) { return ()=>{}; }
async reset() {} // eslint-disable-line
evict(options) { return false; }
restore(data) { return this; }
extract(optimistic) { return emptyCacheObj; }
removeOptimistic(id) {}
batch(options) { return undefined as any; }
performTransaction(update, optimisticId) {}
recordOptimisticTransaction(transaction, optimisticId) {}
transformDocument(document) { return document; }
transformForLink(document) { return document; }
identify(object) { return undefined; }
gc() { return [] as string[]; }
modify(options) { return false; }
readQuery(options, optimistic?) { return null; }
readFragment(options, optimistic?) { return null; }
writeQuery(opts) { return undefined; }
writeFragment(opts) { return undefined; }
updateQuery(options, update) { return null; }
updateFragment(options, update) { return null; }
}
然后我将它连接到Apollo客户端,就像这样:
apolloClient = new ApolloClient({
// replace InMemoryCache with VoidCache, because even a "not used" InMemoryCache can have noticeable overhead
cache: new VoidCache(),
// these config-changes might not be necessary, but I've kept them anyway
defaultOptions: {
watchQuery: {
fetchPolicy: "no-cache",
errorPolicy: "ignore",
},
query: {
fetchPolicy: "no-cache",
errorPolicy: "all",
},
},
});
目前看起来运行良好(避免了性能损失),但如果有问题需要调整,我会更新这个答案。
(注意:apollo-client的缓存结构随着时间的推移而发生了变化。我的答案仅显示了@apollo/client
版本3.7.15
的工作结构。如果您需要旧版本的结构,请查看答案历史记录:3.5.0-beta.4
。)
network-only
。 - Robin Wieruch