如何告诉apollo-client不要在特定字段上应用规范化?

时间:2019-01-22 11:23:57

标签: graphql apollo apollo-client

我的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可以做到吗?我找不到解决办法。

也欢迎提出一种更好的方法来建模此“图形”。

1 个答案:

答案 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毫秒对于处理如此大量的对象来说不是一个坏时机,并且阿波罗内存仍然是一个非常可靠的选择。