【问题标题】:Apollo-Client - Long query plus short query vs. one query to rule them all, which one makes more sense memory-wise?Apollo-Client - 长查询加短查询与一个查询来统治它们,哪一个在记忆方面更有意义?
【发布时间】:2019-06-26 17:40:39
【问题描述】:

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

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

所以问题是,我是否也需要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
        }
    }
`;

【问题讨论】:

    标签: graphql apollo react-apollo apollo-client


    【解决方案1】:

    简短回答:查询拆分肯定有好处,但它在于改善用户体验,并且只能通过正确配置的 InMemoryCache 来实现。

    Apollo 中的查询结果被标准化:

    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 中缓存的工作方式,因此不会影响内存量或突变后更新缓存的难度。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-30
      • 2013-03-30
      • 2011-05-09
      • 2018-03-12
      • 2019-11-05
      • 2014-10-14
      • 2016-09-19
      相关资源
      最近更新 更多