Apollo-Client-长查询加短查询与一个查询来统治所有查询,哪一个在内存方面更有意义?

时间:2019-02-02 08:51:14

标签: graphql apollo react-apollo apollo-client

我的用户查询越来越长,我正在考虑将其分为两个查询,一个ME_QUERY具有最常用的参数,如userType,userName,userID和一个USER_QUERY包含我需要为用户提供的所有参数,但是USER_QUERY仅在用户设置和付款页面中需要,而ME_QUERY几乎用于所有组件,因为我userType到处都需要ACL

但是我不确定将它们分成两个查询是否是一个好主意,因为它们都被缓存在内存中自己的空间中,因此,将它们分开意味着在内存中占据两个位置,同时查询时间很长,会很长,但是只会在内存中保留一个位置,并且在突变后对其进行更新也将更加容易。

所以现在的问题是,我需要ME_QUERY过或USER_QUERY用户登录后,就足够了,其已经跑了一次?

以下是两个查询:

export const USER_QUERY = gql`
    query {
        user {
            uid
            avatar
            isAdmin
            projectCount
            sessions
            providers
            payments // is a long object itself
            coupon
            credits
            email
            userName
            userType
            createdAt
            hasPassword
            companyName
            vatNumber
            addressLine1
            addressLine2
            country
            companySize
        }
    }
`;

export const ME_QUERY = gql`
    query {
        user {
            uid
            avatar
            isAdmin
            email
            userName
            userType
            createdAt
        }
    }
`;

1 个答案:

答案 0 :(得分:1)

简短的回答:查询拆分肯定有好处,但是它可以为您的用户带来更好的体验,只有使用正确配置的InMemoryCache才能实现。

阿波罗中的查询结果已标准化:

  

InMemoryCache通过将结果拆分为单个对象,为每个对象创建唯一的标识符并将这些对象存储在扁平化的数据结构中,从而在将数据保存到存储之前对数据进行规范化。默认情况下,InMemoryCache将尝试使用id和_id的常见主键作为唯一标识符(如果它们与__typename一起存在于对象上)。

如果您在用户查询中没有看到此行为,则可能是因为您的id字段被称为uid而不是id_id。您需要实现自定义dataIdFromObject函数as outlined in the docs

import { InMemoryCache, defaultDataIdFromObject } from 'apollo-cache-inmemory'

const cache = new InMemoryCache({
  dataIdFromObject: object => {
    switch (object.__typename) {
      // or whatever your user type is called
      case 'User': return `${object.__typename}:${object.uid}`
      // other types here that don't have an id or _id 
      default: return defaultDataIdFromObject(object)
    }
  }
})

在您的问题上下文中,具有正确配置的缓存意味着两件事:

  • 使用相同的缓存键获取对象的查询将合并其结果。
  • 返回与现有缓存键匹配的对象的突变将自动更新该对象。

这意味着您可以拆分user查询,并请求最少数量的字段来初始加载页面,并延迟请求其余字段,直到用户导航到需要这些字段的页面为止。您甚至可以使用prefetching提前获取第二个查询。

此外,如果您有一个可以更新用户的突变,只要该突变返回的对象具有匹配的缓存键(即,在这种情况下,它包含一个guid),它将自动更新该对象的缓存。在这种情况下,无需重新查询或手动更新商店-Apollo会为您处理所有事情。

侧面说明:缓存中的对象列表不受上述影响。如果某个突变导致需要在列表中添加或删除某些内容,则Apollo无法推断受影响的列表。在这种情况下,您将update the cache yourself

查询拆分可以使您的应用更快,并改善用户体验,但是由于缓存在Apollo中的工作方式,因此不会对内存量或突变后更新缓存的难度造成影响。

相关问题