代码之家  ›  专栏  ›  技术社区  ›  sarfata

如何告诉apollo客户端不要对特定字段应用规范化?

  •  0
  • sarfata  · 技术社区  · 7 年前

    我的GraphQL模式包括具有大型数据数组的对象,这些数据数组对此对象是唯一的,在其他对象中找不到。

    例如:

    type Position {
      time: Integer
      latitude: Float
      longitude: Float
    }
    
    type ObjectInSpaceAndTime {
      name: String
      positions(start: Int, end: Int): [Position]
    }
    

    我对GraphQL客户端规范化的理解是,响应图将被展平,每个 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客户端不要尝试将其正常化,只存储 ObjectInSpaceAndTime 以及传递给字段的参数,以便具有不同属性的查询生成缓存未命中。 这将大大减少阿波罗在处理回复时在内存中所做的工作。数据数组将从响应中反序列化一次,无需apollo客户端对其进行迭代即可使用。

    {
      __ObjectInSpaceAndTime.someid: {name: 'xxx', 
           positions: [ {time: 1221121, latitude: 0, longitude: 0}, 
                        {time: 1221122, latitude:0, longitude: 0}, 
                        /* ... */ ], 
      // ...
    }
    

    阿波罗的客户可以这样做吗?我找不到办法。

    对于如何更好地为这个“图形”建模的建议,我们也表示欢迎。

    1 回复  |  直到 7 年前
        1
  •  1
  •   sarfata    7 年前

    到目前为止,我找到的最佳解决方案是切换到另一个缓存,即 apollo-cache-hermes .Hermes将只存储他们所称的“实体”,即返回的带有“id”的对象(我正在简化,但这是默认行为)。

    我编写了一个简单的基准测试工具,获取一个包含12k个“点”数组的对象。该点的一个属性是带有纬度和经度键的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
    

    缓存中的处理时间: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

    (我多次运行测试,处理时间变化不大)。

    对我来说,这似乎是一个很好的解决方案,尽管我很惊讶apollo inmemory能够以如此快的速度响应第二个查询。655ms是处理如此大量对象的好时机,apollo inmemory仍然是一个非常可靠的选择。

    推荐文章