Skip to content

[google_maps_flutter] App is lagging when initializing Google Maps #28493

Closed
flutter/packages
#9674

Description

@ItsPierre

I am just building the Google-Maps widget in my Stateful Widget. This will be opened with the Navigator via a Button click. But as soon, as I click, the app is lagging, while initializing the map.
When removing the widget, everything is fine.

I tried to set a CircularProgressIndicator and then, setting the map-widget async, but running into the same problem, as soon, as it gets build.
I also downloaded and ran the example app from the google-maps-package with the same lagging.

How should the map be initilized, that it is first loaded and then set without lagging?

Flutter Doctor

I am developing with Android Studio

[√] Flutter (Channel dev, v1.2.2, on Microsoft Windows [Version 10.0.17763.316], locale de-DE)
    • Flutter version 1.2.2 at S:\Development\Flutter\Flutter-SDK
    • Framework revision 007a415c2a (5 days ago), 2019-02-21 20:22:47 -0800
    • Engine revision f1f19bba8f
    • Dart version 2.2.0 (build 2.2.0-dev.2.1 c92d5ca288)

[√] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
    • Android SDK at C:\Users\Pierre\AppData\Local\Android\sdk
    • Android NDK location not configured (optional; useful for native profiling support)
    • Platform android-28, build-tools 28.0.3
    • Java binary at: S:\Development\Android Studio\jre\bin\java
    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1248-b01)
    • All Android licenses accepted.

[√] Android Studio (version 3.3)
    • Android Studio at S:\Development\Android Studio
    • Flutter plugin version 33.3.1
    • Dart plugin version 182.5215
    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1248-b01)

[!] IntelliJ IDEA Ultimate Edition (version 2018.3)
    • IntelliJ at S:\Development\JetBrains\IntelliJ IDEA 2018.3.2
    X Flutter plugin not installed; this adds Flutter specific functionality.
    X Dart plugin not installed; this adds Dart specific functionality.
    • For information about installing plugins, see
      https://flutter.io/intellij-setup/#installing-the-plugins

[√] Connected device (1 available)
    • Android SDK built for x86 • emulator-5554 • android-x86 • Android 9 (API 28) (emulator)

! Doctor found issues in 1 category.

Activity

  1. added this to the milestone on Feb 26, 2019
  2. zoechi commented on Feb 26, 2019

    @zoechi
    Contributor

    Please add the output of flutter doctor -v.

  3. zoechi commented on Feb 26, 2019

    @zoechi
    Contributor

    Have you tried with a release build? Debug builds are never representative for measuring performance.

  4. ItsPierre commented on Feb 26, 2019

    @ItsPierre
    Author

    Please add the output of flutter doctor -v.

    I will add the flutter doctor -v later

    Have you tried with a release build? Debug builds are never representative for measuring performance.

    Yes, I did try release builds, but it is still lagging, when initializing

  5. ItsPierre commented on Feb 26, 2019

    @ItsPierre
    Author

    Please add the output of flutter doctor -v.

    I added the flutter doctor. But I think, this is a general problem.

  6. zoechi commented on Feb 27, 2019

    @zoechi
    Contributor

    But I think, this is a general problem.

    It's not about possible errors flutter doctor might report.
    flutter doctor -v output is valuable information about the context where the problem reproduced for you.

  7. realvotum commented on Mar 20, 2019

    @realvotum

    Same for me. It takes a while to build my StatelessWidget with google map inside SizedBox 300x300. Without google maps, the widget builds instantly, otherwise the delay for the StatelessWidget to appear is noticeable. This is my output:

    [✓] Flutter (Channel stable, v1.2.1, on Mac OS X 10.14.3 18D109, locale pl-PL)
    • Flutter version 1.2.1 at /Users/mat/dev/flutter
    • Framework revision 8661d8a (5 weeks ago), 2019-02-14 19:19:53 -0800
    • Engine revision 3757390
    • Dart version 2.1.2 (build 2.1.2-dev.0.0 0a7dcf17eb)

    [✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
    • Android SDK at /Users/mat/Library/Android/sdk
    • Android NDK location not configured (optional; useful for native profiling support)
    • Platform android-28, build-tools 28.0.3
    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1248-b01)
    • All Android licenses accepted.

    [✓] iOS toolchain - develop for iOS devices (Xcode 10.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 10.1, Build version 10B61
    • ios-deploy 1.9.4
    • CocoaPods version 1.5.3

    [✓] Android Studio (version 3.3)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin version 33.3.1
    • Dart plugin version 182.5215
    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1248-b01)

    [✓] Connected device (1 available)
    • Android SDK built for x86 • emulator-5554 • android-x86 • Android 8.1.0 (API 27) (emulator)

    • No issues found!

  8. JRR-OSU commented on Mar 29, 2019

    @JRR-OSU

    Experiencing the same in my release builds. Quite a bit of jank.

    I'm not sure how this one can easily be solved as embedding a native platform view as expensive as a Google Map view isn't going to be easy without hindering Flutter's UI performance.

  9. eopeter commented on Jul 7, 2019

    @eopeter

    For now I added a delay in initState to load Google Maps:

    Future.delayed(const Duration(milliseconds: 500), () {
    setState(() {
    _showGoogleMaps = true;
    });
    });

  10. danielcmm commented on Jul 10, 2019

    @danielcmm

    Using this plugin really degrades the performance of the Widget tree for me... i had to put the map on a separate, isolate screen ;/

  11. dshukertjr commented on Dec 3, 2019

    @dshukertjr

    @danielcmm How do you put a widget on a separate isolate?

  12. 49 remaining items

  13. filiph commented on Jun 4, 2025

    @filiph
    Contributor

    Thanks for the info, @JRR-OSU!

    @stuartmorgan-g, it looks like a good way to address this issue would be to give Flutter developers a way to "warm up" Google Maps on demand. Is this something you'd consider merging if I made a PR?

    Here are the PROs and CONs I can see from where I'm standing.

    PROs:

    1. Addresses one of the most-voted-for and infamous issues on this plugin — i.e. clearly something people struggle with.
    2. Follows what native Android developers are doing to address the same issue.
    3. Doesn't require a whole lot of new code nor changes to the engine; can be done today.

    CONs:

    1. "Gives up" on fixing the underlying issue (Google Maps hogging the main thread) - instead gives people a workaround
    2. It could be argued that Flutter developers already have the ability to warm up (by changing android .java or .kt files in their Flutter project)
  14. stuartmorgan-g commented on Jun 4, 2025

    @stuartmorgan-g
    Contributor
    1. Addresses one of the most-voted-for and infamous issues on this plugin — i.e. clearly something people struggle with.

    Maybe. I would imagine that most people are voting to express that they want there not to be lag, not to express that they want the same amount of lag at a different time.

    That's not to say that it isn't potentially useful, but it seems unlikely that it will actually result in most people who voted for it feeling that it's addressed.

    1. "Gives up" on fixing the underlying issue (Google Maps hogging the main thread) - instead gives people a workaround

    I don't follow. How does providing a Dart affordance for an existing workaround impact future Google Maps SDK development? If this behavior is inherent to the SDK, nobody on the Flutter team or in the Flutter community can change that.

    I'd like to understand the problem more before we add a new API though. The fact that the links you've found are all old, and the issue is marked obsolete, makes it unclear to me to what extent this should still be an issue. The Android SDK has an initialization system now; did your sample app call it? Did that change how much work onCreate does?

  15. filiph commented on Jun 12, 2025

    @filiph
    Contributor

    Maybe. I would imagine that most people are voting to express that they want there not to be lag, not to express that they want the same amount of lag at a different time.

    Help me understand. Are you saying that developers who voted on this issue aren't interested in ways to mitigate the lag unless it completely removes the lag? Why do you think so?

    We have a chance to give developers the option to warm up a subsystem so that it doesn't lag at one of the worst times an app can lag (just after user interaction; when the app is most likely transitioning to a new page; when an animation is most likely running). See also time scales in UX by Jakob Nielsen.

    From this perspective, I think it's a bit strange to dismiss the mitigation with "they want the same amount of lag at a different time". I obviously can't talk for anyone else but FWIW, when I can't avoid lag in an app, I do try to manage when it happens. During transition, after human interaction, is much worse than during app startup, for example.

    Yes, it would be ideal to have no lag at all — we can all agree. But that's not clearly possible even when using native Android (see #28493 (comment) above).

    That's not to say that it isn't potentially useful, but it seems unlikely that it will actually result in most people who voted for it feeling that it's addressed.

    Are you merely expressing doubt that this mitigation will be enough for the people who voted for this issue? Or are you saying I should create a separate issue only for people who want to mitigate the issue, and keep this one for the developers that you assume are only waiting for solution to the underlying problem?

    1. "Gives up" on fixing the underlying issue (Google Maps hogging the main thread) - instead gives people a workaround

    I don't follow. How does providing a Dart affordance for an existing workaround impact future Google Maps SDK development? If this behavior is inherent to the SDK, nobody on the Flutter team or in the Flutter community can change that.

    Sorry for not being clear. I was trying to express that by going with the mitigation, I would "give up" on trying to find a fix for the underlying issue. I was not talking about others.

    I'd like to understand the problem more before we add a new API though. The fact that the links you've found are all old, and the issue is marked obsolete, makes it unclear to me to what extent this should still be an issue. The Android SDK has an initialization system now; did your sample app call it? Did that change how much work onCreate does?

    Thanks for mentioning the initialization system (MapsInitializer). It's already being used by the package, and in fact the example in google_maps_flutter_android calls it from main() (here). Maybe I'm holding it wrong, but in my testing, adding the initialization step doesn't have any significant effect on the lag.

    Without pre-initialization:

    Image

    With pre-initialization:

    Image

    I was worried that maybe I'm not initializing the latest renderer (which is supposed to be much more performant than the old one) but I just confirmed I get AndroidMapRenderer.latest from initializeWithRenderer().

  16. stuartmorgan-g commented on Jun 12, 2025

    @stuartmorgan-g
    Contributor

    Since it's still happening with the latest renderer and having already called the initializer, I'm fine with adding an API that would allow pre-creating a temporary invisible map.

  17. filiph commented on Jul 7, 2025

    @filiph
    Contributor

    Ok, I have a question or two before I create the PR, and some results that I'd like to show so that you can decide if the improvement is worth it.

    Here's the improvement in video:

    open.mp4

    Note:

    • The circular progress indicator is there just as a way to visualize jank. Nothing is actually loading — it's just the easiest way I know to show continuous animation.
    • I sabotaged the demo by missing the tap button the first time, and I noticed too late. Now I don't want to retake the video just to remedy this. Hope you can abstract from that issue.

    Actually, it's much easier to see all the subtle differences when the video is 4x slower:

    open.slow.mp4

    The most important issue being addressed here is the complete lack of any page transition on the left. The warmed-up version also janks, but not nearly as much.

    Finally, here's the effect of the warmup phase on app startup:

    startup.mp4

    As @stuartmorgan-g says, this is not actually removing the jank, it's just moving it to elsewhere. I do think it's better to give the developer an option of when and where to have the largest jank. And I think that for most apps, it's best at the very beginning (as long as we're still talking about sub-second janks, of course, and not some long loading screen).

    Now, an API design question. I originally thought that I'd introduce some kind of separate warmup() function. But it's not clear where to put it, and I think it maybe makes more sense to bundle it with the existing initializeWithRenderer() method. What do you think, @stuartmorgan-g?

      /// Requests Google Map Renderer with [AndroidMapRenderer] type.
      ///
      /// See https://pub.dev/packages/google_maps_flutter_android#map-renderer
      /// for more information.
      ///
      /// The renderer must be requested before creating GoogleMap instances as the
      /// renderer can be initialized only once per application context.
      /// Throws a [PlatformException] if method is called multiple times.
      ///
      /// The returned [Future] completes after renderer has been initialized.
      /// Initialized [AndroidMapRenderer] type is returned.
      ///
      /// When [warmup] is `true`, the plugin will also warm up the Android
      /// Google Maps SDK just after initializing it. This is so that
      /// the first showing of a [GoogleMap] widget doesn't introduce too much jank.
      /// This is a trade-off, since the jank isn't eliminated, only moved.
      Future<AndroidMapRenderer> initializeWithRenderer(
          AndroidMapRenderer? rendererType,
          {bool warmup = false}) async {
        // ...
      }

    The advantages of bundling warmup in initializeWithRenderer:

    1. Minimal change to API - just a new optional argument
    2. No way for the developer to screw this up (e.g. calling warmup before initialize)
    3. Slightly easier to implement
    4. Warming up after initialization is what I expect 99% of developers to want to do

    The disadvantages:

    1. Less control - the warmup is called just after initialization, but that initialization is asynchronous, and could therefore happen at a bad time. Some developers might want to wait for a more opportune time.
  18. stuartmorgan-g commented on Jul 15, 2025

    @stuartmorgan-g
    Contributor

    4. Warming up after initialization is what I expect 99% of developers to want to do

    I don't see any reason to expect that developers with apps that only show maps in specific flows wouldn't want to separate renderer initialization (presumably cheap, but async with a server component) with the unrelated warmup step (slow/janky).

  19. filiph commented on Jul 15, 2025

    @filiph
    Contributor
    1. Warming up after initialization is what I expect 99% of developers to want to do

    I don't see any reason to expect that developers with apps that only show maps in specific flows wouldn't want to separate renderer initialization (presumably cheap, but async with a server component) with the unrelated warmup step (slow/janky).

    Ok, I see a reason or two but moving on. So you want me to create a new method on the same object, then? Any preference on naming? Should it throw if used before initializeWithRenderer or should it call that method automatically when appropriate?

  20. stuartmorgan-g commented on Jul 15, 2025

    @stuartmorgan-g
    Contributor

    So you want me to create a new method on the same object, then? Any preference on naming?

    It would be a method on GoogleMapsFlutterAndroid, yes. I'll defer to the Android subteam on naming; that can be figured out in review as it's relatively minor.

    Should it throw if used before initializeWithRenderer or should it call that method automatically when appropriate?

    I don't understand the question; initializeWithRenderer isn't a required method, so I wouldn't expect it to do either of those things.

  21. added
    r: fixedIssue is closed as already fixed in a newer version
    on Aug 7, 2025
  22. github-actions commented on Aug 21, 2025

    @github-actions

    This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

  23. locked as resolved and limited conversation to collaborators on Aug 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Issues that are less important to the Flutter projecta: qualityA truly polished experiencec: performanceRelates to speed or footprint issues (see "perf:" labels)customer: crowdAffects or could affect many people, though not necessarily a specific customer.found in release: 2.1Found to occur in 2.1has reproducible stepsThe issue has been confirmed reproducible and is ready to work onp: mapsGoogle Maps pluginpackageflutter/packages repository. See also p: labels.r: fixedIssue is closed as already fixed in a newer versionteam-ecosystemOwned by Ecosystem teamtriaged-ecosystemTriaged by Ecosystem team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions