如何告诉 apollo-client 不要对特定字段应用规范化?
How to tell apollo-client to not apply normalization on specific fields?
我的 GraphQL 架构包括具有大量数据的对象,这些数据是该对象独有的,不会在其他对象中找到。
示例:
type Position {
time: Integer
latitude: Float
longitude: Float
}
type ObjectInSpaceAndTime {
name: String
positions(start: Int, end: Int): [Position]
}
我对 GraphQL Client 规范化的理解是,响应图将被展平,Position
的每个实例在缓存中提取,为其创建一个唯一的键(从位置的路径,所以像someobject.positions.42
)。这是非常 CPU 和内存密集型的,有数千个值。
缓存将如下所示:
{
__ObjectInSpaceAndTime.someid: {name: 'xxx'},
__ObjectInSpaceAndTime.someid.positions.0: {time: 1221121, latitude: 0, longitude: 0},
__ObjectInSpaceAndTime.someid.positions.1: {time: 1221122, latitude: 0, longitude: 0},
// ...
}
相反,我想告诉 Apollo Client 不要尝试对其进行规范化,而只是存储 ObjectInSpaceAndTime
的整个实例及其字段,也许还有传递给字段的参数,以便具有不同的查询属性产生缓存未命中。
这将显着减少 apollo 在处理回复时必须在内存中做的工作。数据数组将从响应中反序列化一次,无需 apollo-client 迭代即可使用。
{
__ObjectInSpaceAndTime.someid: {name: 'xxx',
positions: [ {time: 1221121, latitude: 0, longitude: 0},
{time: 1221122, latitude:0, longitude: 0},
/* ... */ ],
// ...
}
Apollo Client 可以吗?我找不到办法做到这一点。
也欢迎就此建模的更好方法提出建议 "graph"。
到目前为止我找到的最佳解决方案是切换到另一个缓存,即apollo-cache-hermes。 Hermes 只会存储他们所谓的 "Entities",即返回一个带有 'id' 的对象(我正在简化,但这是默认行为)。
我写了一个简单的基准测试工具,获取一个关联了 12k "points" 数组的对象。该点的属性之一是带有纬度和经度键的 GPS 坐标。
使用默认的 apollo-inmemory 缓存,我得到:
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
缓存中的处理时间:655 毫秒
与 apollo-hermes:
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
(我运行多次测试,处理时间相差不大)。
虽然我对 apollo-inmemory 对第二个查询的响应速度如此之快感到惊讶,但对我来说这似乎是一个很好的解决方案。 655 毫秒是处理如此大量对象的不错时间,内存中的 apollo 仍然是一个非常可靠的选择。
我的 GraphQL 架构包括具有大量数据的对象,这些数据是该对象独有的,不会在其他对象中找到。
示例:
type Position {
time: Integer
latitude: Float
longitude: Float
}
type ObjectInSpaceAndTime {
name: String
positions(start: Int, end: Int): [Position]
}
我对 GraphQL Client 规范化的理解是,响应图将被展平,Position
的每个实例在缓存中提取,为其创建一个唯一的键(从位置的路径,所以像someobject.positions.42
)。这是非常 CPU 和内存密集型的,有数千个值。
缓存将如下所示:
{
__ObjectInSpaceAndTime.someid: {name: 'xxx'},
__ObjectInSpaceAndTime.someid.positions.0: {time: 1221121, latitude: 0, longitude: 0},
__ObjectInSpaceAndTime.someid.positions.1: {time: 1221122, latitude: 0, longitude: 0},
// ...
}
相反,我想告诉 Apollo Client 不要尝试对其进行规范化,而只是存储 ObjectInSpaceAndTime
的整个实例及其字段,也许还有传递给字段的参数,以便具有不同的查询属性产生缓存未命中。
这将显着减少 apollo 在处理回复时必须在内存中做的工作。数据数组将从响应中反序列化一次,无需 apollo-client 迭代即可使用。
{
__ObjectInSpaceAndTime.someid: {name: 'xxx',
positions: [ {time: 1221121, latitude: 0, longitude: 0},
{time: 1221122, latitude:0, longitude: 0},
/* ... */ ],
// ...
}
Apollo Client 可以吗?我找不到办法做到这一点。
也欢迎就此建模的更好方法提出建议 "graph"。
到目前为止我找到的最佳解决方案是切换到另一个缓存,即apollo-cache-hermes。 Hermes 只会存储他们所谓的 "Entities",即返回一个带有 'id' 的对象(我正在简化,但这是默认行为)。
我写了一个简单的基准测试工具,获取一个关联了 12k "points" 数组的对象。该点的属性之一是带有纬度和经度键的 GPS 坐标。
使用默认的 apollo-inmemory 缓存,我得到:
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
缓存中的处理时间:655 毫秒
与 apollo-hermes:
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
(我运行多次测试,处理时间相差不大)。
虽然我对 apollo-inmemory 对第二个查询的响应速度如此之快感到惊讶,但对我来说这似乎是一个很好的解决方案。 655 毫秒是处理如此大量对象的不错时间,内存中的 apollo 仍然是一个非常可靠的选择。