我的GraphQL模式包括具有大量数据数组的对象,这些数据对该对象是唯一的,在其他对象中找不到。
示例:
type Position {
time: Integer
latitude: Float
longitude: Float
}
type ObjectInSpaceAndTime {
name: String
positions(start: Int, end: Int): [Position]
}
我对GraphQL Client中的规范化的理解是,响应图将被展平,Position
的每个实例在缓存中提取,为它创建的唯一键(从位置的路径开始,所以类似{{ 1}})。这是非常消耗CPU和内存的,具有数千个值。
缓存将如下所示:
someobject.positions.42
相反,我想告诉Apollo Client不要尝试对其进行规范化,而是仅将{
__ObjectInSpaceAndTime.someid: {name: 'xxx'},
__ObjectInSpaceAndTime.someid.positions.0: {time: 1221121, latitude: 0, longitude: 0},
__ObjectInSpaceAndTime.someid.positions.1: {time: 1221122, latitude: 0, longitude: 0},
// ...
}
的整个实例及其字段以及可能传递给字段的参数存储起来,以便产生具有不同属性的查询缓存未命中。
这将大大减少阿波罗在处理回复时在内存中要做的工作。数据数组将从响应中反序列化一次,并且无需阿波罗客户端即可对其进行迭代即可使用。
ObjectInSpaceAndTime
Apollo Client可以做到吗?我找不到解决办法。
也欢迎提出一种更好的方法来建模此“图形”。
答案 0 :(得分:0)
到目前为止,我发现最好的解决方案是切换到另一个缓存,即apollo-cache-hermes。爱马仕只会存储他们所谓的“实体”,即带有“ id”返回的对象(我正在简化,但这是默认行为)。
我写了一个简单的基准测试工具,获取一个与数组关联的12k个“点”的对象。该点的属性之一是具有经纬度键的GPS坐标。
使用默认的阿波罗内存缓存,我得到:
1st query (not cached)
Network time: 2358ms
Received data navDataCount=12860 Timer=3013ms Memory=82.41MB CacheEntries=25722
2nd query (cached)
Received data navDataCount=12860 Timer=19ms Memory=86.26MB CacheEntries=25722
缓存中的处理时间:655ms
使用阿波罗爱马仕:
1st query (not cached)
Network time: 2891ms
Received data navDataCount=12860 Timer=3079ms Memory=23.36MB CacheEntries=3
2nd query (cached)
Received data navDataCount=12860 Timer=51ms Memory=22.37MB CacheEntries=3
缓存中的处理时间:188ms
(我多次运行测试,处理时间并没有太大变化)。
对我来说似乎是一个很好的解决方案,尽管令我惊讶的是,阿波罗内存能够对第二个查询做出快速的响应。 655毫秒对于处理如此大量的对象来说不是一个坏时机,并且阿波罗内存仍然是一个非常可靠的选择。