📝

ApolloClientのInMemoryCacheの上限と挙動について

2022/02/27に公開約2,000字

概要

Node.jsでGraphQLを実装する場合に、ApolloClientを使用する場合がある。
このApolloClientのInMemoryCacheを使用した場合のキャッシュの上限についての調査を行う。

ApolloClientのキャッシュの概要については以下を参照

https://www.apollographql.com/docs/react/caching/overview/

InMemoryCacheの機構

resultCachMaxSizeによる上限指定

appoloCLient 3.xではresultCacheMaxSizeが指定できてキャッシュに蓄えることができるオブジェクトの数の上限を指定できる。

https://github.com/apollographql/apollo-client/pull/8107

使用例:

const cache = new InMemoryCache({ resultCachMaxSize: 5000 });

この上限を超えた場合、古く参照したものから削除されると考えられる。

optimism

InMemoryCacheは内部でoptimismというライブラリを使用している

https://github.com/apollographql/apollo-client/blob/main/package.json#L89

optimismはリアクティブなキャッシュで以下からコードが確認できる。

https://github.com/benjamn/optimism/tree/cd93f7a119566bb10390e00ad2a990a7a131362b

もし、InMemoryCacheでresultCachMaxSizeを指定しない場合、この上限は「Math.pow(2, 16)」となる。

https://github.com/benjamn/optimism/blob/cd93f7a119566bb10390e00ad2a990a7a131362b/src/index.ts#L91

また、以下のロジックを確認することで、最も参照したのが古いものから消えていることが確認できる。

https://github.com/benjamn/optimism/blob/cd93f7a119566bb10390e00ad2a990a7a131362b/src/cache.ts#L29
https://github.com/benjamn/optimism/blob/cd93f7a119566bb10390e00ad2a990a7a131362b/src/cache.ts#L88

キャッシュのリセットについて

テストを行う際など、キャッシュをリセットしたい局面がある。
この場合は、以下にあるように、client.resetStoreを使用することでキャッシュが削除される。

https://www.apollographql.com/docs/react/caching/advanced-topics/#resetting-the-cache

また、キャッシュをクリアするということは、それを参照していた箇所で予期せぬ動作を引き起こすことが想像できる。
この場合、client.onResetStoreでコールバックを指定することにより、キャッシュをリセットした場合に、初期値を設定することが可能になる。

キャッシュの個別削除

ApolloClient3ではevictとgcを使用することで、特定のキャッシュを削除することが可能である。

https://www.apollographql.com/docs/react/caching/garbage-collection/

ブラウザからキャッシュの状態を確認する方法

以下から確認可能。

window.__APOLLO_CLIENT__.cache

また、Chromeの拡張機能も存在するのでそれで確認可能

https://chrome.google.com/webstore/detail/apollo-client-devtools/

apolloClientのキャッシュの考察

上記にあるようにキャッシュには上限があり、特定の大きさを蓄えると古いものから消える。
これは明示的にクリアすることが可能である。

また、apolloClientのキャッシュをローカルの状態を蓄えることもできるが、キャッシュの上限があり、それが消える場合もあるとした場合、消えて困るデータをこの機構を使用して保持するのはリスクがあると考えられる。

Discussion

ログインするとコメントできます