apollographql / apollo-client

:rocket:  A fully-featured, production ready caching GraphQL client for every UI framework and GraphQL server.
https://apollographql.com/client
MIT License
19.38k stars 2.66k forks source link

Performance Umbrella Issue #1409

Closed Poincare closed 7 years ago

Poincare commented 7 years ago

This issue is meant to describe current tasks related to improving Apollo Client store performance and serve as a summary about the information we currently know about Apollo Client's perf. characteristics.

The primary issue that we are concerned with at the moment is store read performance. This is probably the operation that Apollo Client performs the most since apps don't write new results or send new queries over the network that often. We know a few pieces of information about the store read performance as measured through the benchmarks.

No-fetch query vs diffQueryAgainstStore

There are two ways we can look at cache read performance. We can either fire a client.query({ noFetch: true }) call or we can directly call diffQueryAgainstStore. The former also counts the time it takes to set up all of the surrounding logic (e.g. set up and tear down of the ObservableQuery, delivering the result to the query observers, etc.) whereas the latter does not.

So, we if we compare these on reading a GraphQL result that contains a list of objects out of the store, we can tell whether most of the time is spent on denormalization or in just setting up the stuff surrounding query. Results:

graph

As evident from above, query takes ~10-15x the time as diffQueryAgainstStore to read a result with the same number of associated objects. This probably implies that our logic within QueryManager and ObservableQuery can be improved and also probably means that the de-normalization that lives inside diffQueryAgainstStore isn't the primary culprit, especially for the counts of items considered in the above plot.

REC

As mentioned in #1242, referential equality checking (REC) imposes some cost on the store read times as measured through a no-fetch query. Here are the reproduced results:

graph

The blue line is with REC and the pink line is without. We can also see that resultMapper and addPreviousResultToIdValues (both tied to REC, afaik) play a significant role in the CPU profile for the noFetch query benchmark:

cpu profile

I'm not sure if this perf. hit is expected or if it's a consequence of an implementation bug. If it is the former, we can just offer an option to allow the application developer to turn off REC. That way, the tradeoff between preventing a React re-render and going through REC can be made at the application level.

Tasks

  1. Investigate why a noFetch query takes so long in comparison to diffQueryAgainstStore and make it better (currently working on this)
  2. Figure out why REC takes time
  3. (Maybe?) Attempt to improve graphql-anywhere performance for diffQueryAgainstStore

Comments would be great.

chompomonim commented 7 years ago

Dear bot, please don't touch this issue. It's quite important one.

jbaxleyiii commented 7 years ago

@chompomonim you can now tell the bot to not mark an issue using labels. Take a look at #1924 for more information!

elie222 commented 7 years ago

Yes, we've run into this issue too. Apollo being super slow for us. Need to work around this somehow. Not sure how right now.

nerdmed commented 7 years ago

@helfer any news on this one or any plans you guys could share regarding apollo performance? We also found some performance issues on slower devices that totally break the UX.

ephemer commented 7 years ago

Adding some more info to avoid this issue being closed: we're having issues with Apollo Client performance in React Native on older devices (anything older than an iPhone 6). Part of this is probably due to JSCore not allowing JIT outside of WKWebView, leaving us with a pretty poor performance baseline for JS to begin with. We're investigating too.

elie222 commented 7 years ago

Our Android React Native performance is awful. Not sure if this is Apollo or not. We know for certain that having too many items in the Apollo client store is a recipe for disaster though. Hopefully 2.0 fixes it.

On 11 Aug 2017 15:29, "Geordie J" notifications@github.com wrote:

Adding some more info to avoid this issue being closed: we're having issues with Apollo Client performance in React Native on older devices (anything older than an iPhone 6). Part of this is probably due to JSCore not allowing JIT outside of WKWebView, leaving us with a pretty poor performance baseline for JS to begin with. We're investigating too.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/apollographql/apollo-client/issues/1409#issuecomment-321800074, or mute the thread https://github.com/notifications/unsubscribe-auth/AC8oXyw3Mf43q7g4sjMlyJg9nz1oTKW7ks5sXEkogaJpZM4Ma3xM .

stale[bot] commented 7 years ago

This issue has been automatically marked as stale becuase it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions to Apollo Client!

nerdmed commented 7 years ago

Dear bot, please don't touch this issue. It's quite important one. 👍

jbaxleyiii commented 7 years ago

The 2.0 has around a 5x performance jump and new cache implementations (like apollo-cache-hermes) can increase this jump even more! I think its time to close this issue for the 1.* line and open a new one for the 2.0 if / when needs come up!