Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

makeCacheKey performance becomes extremely slow after dozens of calls & refetchQueries fails to update query with no-cache fetchPolicy #8788

Open
conoremclaughlin opened this issue Sep 15, 2021 · 1 comment

Comments

@conoremclaughlin
Copy link

Intended outcome:

We discovered that running multiple instances of useQuery with a cache-and-network fetchPolicy (say over 100 calls within a 5 minute window) caused component rendering to lag over time. A browser performance recording suggested makeCacheKey was mainly responsible, as such we decided to run useQuery with no-cache instead. This fixed our performance issue but caused components that relied on refetchQueries for re-rendering to no longer refetch.

Intended outcome would be we can use Apollo's cache and have performance maintain for longer than 5 minutes while doing common look ups OR using refetchQueries WITH string arguments would successfully refetch for queries with variables. We have been unable to get either direction to work.

Actual outcome:

Performance - significantly lags and bogs down all other activity on the main thread.

Lag can be seen here:
Screenshot 2021-09-15 at 12 00 57 AM

With no lag being seen once we switched to 'no-cache'
Screenshot 2021-09-15 at 12 03 54 AM

refetchQueries using Words or Words($words: [String!]) both fail despite us following the recommendation here:
#7830 (comment)

It's possible we've been mislead by the types as to the power of refetchQueries outside of React. Because this is our Web extension, we cannot interact with Apollo only through the context of React. There are multiple environments, events to handle, react apps to mount, etc.

How to reproduce the issue:

Here are the calls that are failing:

  // query
  export const wordsQueryGql = gql`
    query Words($words: [String!]) {
      words(words: $words) {
        word
        language
        createdAt
        updatedAt
      }
  }
  `;

   // useQuery hook
   const { loading, data, error, refetch } = useQuery(wordsQueryGql, {
    fetchPolicy: 'no-cache',
    variables: {
      words,
      language: targetLanguage,
    },
  });

  // mutation
  client.mutate({
      mutation: wordsToggleSaveGql,
      variables: {
        input: {
          word,
          language: this.targetLanguage,
        },
      },
      refetchQueries: [
        'Words($words: [String!])', // also 'Words'
      ],
    });

Versions

Node: 12.18.4 - ~/.nvm/versions/node/v12.18.4/bin/node
Yarn: 1.22.10 - ~/.nvm/versions/node/v12.18.4/bin/yarn
npm: 6.14.6 - ~/.nvm/versions/node/v12.18.4/bin/npm npmPackages:
@apollo/client: ^3.3.19 => 3.3.19

Thank you all for the hard work! If we've missed something in the documentation or a key concept, let us know. I've created one issue since the second refetchQueries portion may be a misunderstanding of us on how Apollo is supposed to be used.

@benjamn
Copy link
Member

benjamn commented Sep 15, 2021

One small note: Chrome devtools uses some imperfect heuristics to figure out appropriate function names for stack trace items, and makeCacheKey (though not expensive itself) often shows up incorrectly as the name of other, more expensive cache reading work. If you zoom into the flame chart, you might be able to get a better sense for where time is spent.

As you've realized, using no-cache can be a good temporary/diagnostic tool, but has some significant limitations, so it's never really the best answer to problems with the cache.

Some recent performance work that could be relevant here: #8734

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants