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

Slow queries when hitting the cache #8681

Open
cedvdb opened this issue Dec 15, 2024 · 5 comments
Open

Slow queries when hitting the cache #8681

cedvdb opened this issue Dec 15, 2024 · 5 comments

Comments

@cedvdb
Copy link

cedvdb commented Dec 15, 2024

Operating System

ubuntu

Environment (if applicable)

Version 131.0.6778.85 (Official Build) (64-bit)

Firebase SDK Version

10.11.1

Firebase SDK Product(s)

Firestore

Project Tooling

Flutter

Detailed Problem Description

I have a minimal reproduction sample (as much as I could) where a simple query hitting the cache takes a whopping 45 seconds to resolve.

During my trials to reproduce this issue I've found that:

  • The same query, when disableNetwork() is called before writing the data to Firestore takes an order of magnitude less time to resolve. After glancing over index_db, I see that the way data is stored is not the same when network is disabled, which could explain the effect on performances.
  • The same query also resolve normally when there is no flutter animation on the screen.

As I could not isolate the issue to any of those technologies (flutter & firestore), this leads me to believe there are performances issues in both firestore and flutter animation mechanism acting on each other. Furthermore the fact that the query is resolving in normally depending on how it has been written is indicative that there is an issue on the firestore side there.

Steps and code to reproduce issue

Prerequisite: Flutter is required to launch this

  1. Clone https://github.com/cedvdb/flutter_animation_perf branch circular_progress_indicator_firestore_perf_issue
  2. Link a firebase project as described here https://firebase.google.com/docs/flutter/setup?platform=web
  3. Run the example app on the web
  4. Press create data button and wait until the text tells you to reload
  5. Reload the page
  6. Wait at least 2 minutes for the data to load

image

  • After that we are going to delete the local cache, by going in the chrome devtools > application > indexedDB > and then delete all firestore databases.
  • Close the application
  • switch to the branch network_disabled
  • relaunch the application
  • Press create data button and wait 30 seconds, then reload the page (the text will not change this time)
  • It now takes approximately 3 seconds to load the data from cache (still a lot but an order of magnitude less than before).

image

When removing the flutter animation it takes even less time:

image

@cedvdb cedvdb added new A new issue that hasn't be categoirzed as question, bug or feature request question labels Dec 15, 2024
@google-oss-bot
Copy link
Contributor

I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.

@jbalidiong jbalidiong added api: firestore needs-attention and removed needs-triage new A new issue that hasn't be categoirzed as question, bug or feature request labels Dec 16, 2024
@wu-hui wu-hui self-assigned this Jan 15, 2025
@wu-hui
Copy link
Contributor

wu-hui commented Jan 21, 2025

What you saw is an expected behavior. When network is disabled, the SDK reads the results from cache without requesting anything from server, hence the faster turn around because there is no network latency involved.

You can achieve the same result without disabling network, by supplying a source option in https://github.com/firebase/flutterfire/blob/9eac89ebf1faa16966733bc527fb17c66efac654/packages/cloud_firestore/cloud_firestore_platform_interface/lib/src/get_options.dart#L32. Setting source to cache directly should work the same way.

Alternatively, use snapshots instead of get, snapshots will give you the results from cache first, then augment the results with server response in subsequent snapshots, and is recommended over get in general.

@cedvdb
Copy link
Author

cedvdb commented Jan 22, 2025

hence the faster turn around because there is no network latency involved.

You are misunderstanding the issue.

The "faster turnaround" in this case is 50 seconds when no network request (hitting the cache) and 1-2 seconds with a network request. So the cached response was way, way slower.

The issue was flutter blocking the cache request, with the circular progress indicator animation, which made the cached request take 50 seconds. However there is still an issue with how things are cached, because as said in the post, the issue does not appear to begin with in this case:

  1. stop network
  2. create data locally
  3. reload app
  4. query data local cache

But it will happen in this case

  1. enable network
  2. query data from network
  3. disable network
  4. reload app
  5. query data from cache

This means that there is a difference in how things are cached for those 2 scenarios, scenario 1 being more efficient. If I recall correctly, for those two scenarios, it's not written to the same indexed DB table. Unless I did something wrong with the manipulation, both scenarios should have had the same issue.

Note: this is not a big deal (for me), as I solved the flutter issue by using native animation instead of flutter animations. However I can guarantee that people using flutter + firestore + any flutter loading indicator have slower queries than expected when using persistence.

Feel free to close this as this was mostly a Flutter issue (although as said above I believe some parts are inefficient here too).

@MarkDuckworth
Copy link
Contributor

I was reading through this out of curiosity. @cedvdb, your observation is accurate, that the data written to the SDK cache is treated differently between the two tested scenarios. This is intentional. We don't generally get into the details of the implementation, but at a high-level, the data is different types. In the first case, the data is something that has not been written to or acknowledged by the server. In the second case, the cached data is something retrieved from the server. It's not clear to me why you are seeing retrieval of one be more performant than the other.

Re: animation. I'm not too familiar with the flutter animation you are using, but based on the thread you posted on the flutter repo, it sounds like it could be a blocking. Others have reported cpu spikes when using it.

Thanks for posting this and following up with your solution. It may help others resolve the same situation.

@wu-hui
Copy link
Contributor

wu-hui commented Jan 22, 2025

Ah, you are right. Sorry to mis-interpret you. As Mark said, this is a separate issue, queuing up a large number of pending mutations locally can affect query performance.

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

5 participants