[Bug]: [iOS] Navigation SDK init/quota retry loop pins the main thread; React Native's Settings module and addMarker's temporary GMSMarker add to the cost
Maintainer thường phản hồi trong vòng 5 ngày
@illuminati1911 đang làm issue này rồi.
Từ ngày 26/10/2026.
Đánh giá
Issue này chưa được đánh giá.
Mô tả
Is there an existing issue for this?
- I have searched the existing issues
Description of the bug
Summary
On iOS, Navigation SDK 11.1.0 can get stuck retrying its init/quota request with no backoff, on the main thread. While that happens an app uses 100–160 % CPU even when idle, and the UI is sluggish. I've reported the SDK bug to Google, with a native repro: https://issuetracker.google.com/issues/577830531
I'm opening this here because two things make it worse in a React Native app, and one of them is in this wrapper.
Environment
@googlemaps/react-native-navigation-sdk0.17.3- React Native 0.87.1, New Architecture
- Navigation SDK for iOS 11.1.0, Maps SDK for iOS 11.1.0
- iPhone 15 Pro Max, iOS 27.0.1
What triggers the loop
In a native app (no React Native), any GMSNavigationServices call while the terms aren't accepted starts it. Even areTermsAndConditionsAccepted does, and so does the terms dialog while it's open. Accepting the terms stops it. In our React Native app we also saw it with the terms already accepted: on a network whose DNS blocks a Google endpoint (a Pi-hole), and after repeatedly opening and closing a screen with map views.
Through this wrapper, areTermsAccepted(), showTermsAndConditionsDialog() and init() reach those calls, so an app that checks the terms early (for example when a screen mounts) can start the loop with nothing on screen.
Native repro app: https://github.com/filipesteves/navsdk-ios-init-retry-repro
Why it's worse in React Native
1. React Native's Settings module. Each retry writes NSUserDefaults several times (about 1,000 writes a second). React Native's RCTSettingsManager observes NSUserDefaultsDidChangeNotification, and on each one it serialises the whole defaults dictionary and sends it to JS. In Time Profiler that was about half of the main-thread samples during the loop. This is React Native core, not this wrapper, but anyone using the wrapper pays it.
2. addMarker on an existing id builds a temporary GMSMarker. In NavViewModule.mm, addMarker always creates a new GMSMarker (with the icon from imgPath), then NavViewController addMarker:visible:result: copies its properties onto the existing marker. Each new GMSMarker writes NSUserDefaults once, with or without an icon. So every addMarker call is a defaults write, and a full Settings round-trip to JS.
Measured in the native repro, re-adding 10 markers every 0.25 s (40 calls/s):
| How existing markers are updated | defaults writes/s |
|---|---|
Like the wrapper (temporary GMSMarker, then copy) |
40 |
| Directly on the existing marker | 0 |
Marker updates didn't start the retry loop in our tests (11,200 calls and 28 map views over 7.8 minutes, no loop), but they add steady main-thread work in apps that redraw markers often.
Suggestions
- When
addMarkergets an id that already exists, update that marker in place without building a temporaryGMSMarker. - Consider a note in the docs that, on iOS, calling
areTermsAccepted()/init()before the user is about to accept the terms can trigger the SDK's retry loop (until Google fixes the linked bug).
I can open a PR for the first one if that would help.
iOS Platform
Affected
Android Platform
Not verified
React Native version
0.87.1 (New Architecture)
React version
19.2.3
Package version
0.17.3
Native SDK versions
- I haven't changed the version of the native SDKs
React Native Doctor Output
Common
✓ Node.js - Required to execute JavaScript code
✓ npm - Required to install NPM dependencies
✓ Watchman - Used for watching changes in the filesystem when in development mode
✓ Metro - Required for bundling the JavaScript code
Android
✖ Adb - No devices and/or emulators connected. Please create emulator with Android Studio or connect Android device.
✓ JDK - Required to compile Java code
✓ Android Studio - Required for building and installing your app on Android
✖ ANDROID_HOME - Environment variable that points to your Android SDK installation
✓ Gradlew - Build tool required for Android builds
✖ Android SDK - Required for building and installing your app on Android
- Versions found: N/A
- Version supported: 37.0.0
iOS
✓ Xcode - Required for building and installing your app on iOS
✓ Ruby - Required for installing iOS dependencies
✓ CocoaPods - Required for installing iOS dependencies
✓ .xcode.env - File to customize Xcode environment
Errors: 3
Warnings: 0
(The 3 errors are Android tooling on this machine; the issue is iOS-only.)
Steps to reproduce
Marker writes (no retry loop needed):
- Show a
MapVieworNavigationViewwith ~10 markers. - Call
addMarkeragain for the same ids every 250 ms (as an app that redraws markers on each location update does). - Observe
NSUserDefaultsDidChangeNotificationon iOS: one peraddMarkercall (40/s here). With React Native's Settings module, each one sends the whole defaults dictionary to JS.
Retry loop (native SDK bug, linked above):
- Fresh install, terms not accepted.
- Call
navigationController.areTermsAccepted()(or show the terms dialog and leave it open). - Watch CPU in Xcode: 40–160 % while idle until the terms are accepted.
Native repro of both (no React Native): https://github.com/filipesteves/navsdk-ios-init-retry-repro
Expected vs Actual Behavior
Expected: updating an existing marker doesn't write NSUserDefaults, and an idle app stays near 0 % CPU.
Actual: each addMarker call on an existing id writes NSUserDefaults once. Measured in the native repro, re-adding 10 markers every 0.25 s:
| How existing markers are updated | defaults writes/s |
|---|---|
Like the wrapper (temporary GMSMarker, then copy) |
40 |
| Directly on the existing marker | 0 |
Combined with the SDK's retry loop, the app sat at 100–160 % CPU while idle (Time Profiler: GMSNavigationQuotaService sendNavigationInitRequestWithHandler: → GMSDASHProtobufferRequest scheduleRetryIfApplicableForResponse:error:connection:, plus -[RCTSettingsManager userDefaultsDidChange:]).
Code Sample
import { useEffect } from 'react';
import { useNavigation } from '@googlemaps/react-native-navigation-sdk';
// 1. Re-adding markers with existing ids: one NSUserDefaults write per call on iOS.
function redrawMarkers(mapViewController) {
const timer = setInterval(() => {
for (let i = 0; i < 10; i++) {
mapViewController.addMarker({
id: `marker-${i}`,
position: { lat: 37.7793 + 0.006 * Math.sin(i), lng: -122.4193 + 0.008 * Math.cos(i) },
imgPath: 'custom_marker',
});
}
}, 250);
return () => clearInterval(timer);
}
// 2. Checking the terms before they're accepted starts the SDK's retry loop (native bug).
function TermsCheck() {
const { navigationController } = useNavigation();
useEffect(() => {
navigationController.areTermsAccepted();
}, [navigationController]);
return null;
}
Additional Context
- Navigation SDK for iOS 11.1.0, Maps SDK for iOS 11.1.0; iPhone 15 Pro Max, iOS 27.0.1; Xcode 27.0, Debug build.
- Google issue for the retry loop: https://issuetracker.google.com/issues/577830531
- Marker updates alone didn't start the retry loop in our tests (11,200 calls and 28 map views over 7.8 minutes).
- Related, in the native SDK: every
GMSMapView setPadding:call also writesNSUserDefaults, even with an unchanged value. - Happy to open a PR for the in-place marker update.
- Ngôn ngữ chính
- TypeScript
- Star
- 226
- Fork
- 39
- Merge trung bình
- 1 ngày 20 giờ
- Pull request đã merge (30 ngày)
- 7
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của googlemaps/react-native-navigation-sdk
-
[Support Request]: Status of Expo config plugin release (prebuild fails on 0.19.0)Có thể đã có người làm @jokerttu đã nhận 1 ngày trước. Đang mở
googlemaps/react-native-navigation-sdk#711 · 1 người được giao ·
Maintainer thường phản hồi trong vòng 5 ngày
-
[Bug]: In-navigation notification can't be stoppedCó thể đã có người làm @jokerttu đã nhận 8 ngày trước. Đang mởtriage me type: bug
googlemaps/react-native-navigation-sdk#696 · 1 người được giao ·
Maintainer thường phản hồi trong vòng 5 ngày
-
[Bug]: iOS crash in GMSObjectDataCache Core Data save (fatal optimistic locking failure)Có thể làm lại được @illuminati1911 đã nhận 60 ngày trước và không có pull request nào đang mở. Đang mởnative sdk issue
googlemaps/react-native-navigation-sdk#647 · 1 bình luận · 1 người được giao ·
Maintainer thường phản hồi trong vòng 5 ngày
-
[Bug]: CarPlay map view never sets GMSMapViewOptions.screen, so the navigation header and footer are sized for the phoneCó thể làm lại được @jokerttu đã nhận 73 ngày trước và không có pull request nào đang mở. Đang mở
googlemaps/react-native-navigation-sdk#640 · 4 bình luận · 1 reaction · 1 người được giao ·
Maintainer thường phản hồi trong vòng 5 ngày
-
[Bug]: CarPlay Simulator crashes on iOS versions > 26.3Có thể làm lại được @jokerttu đã nhận 155 ngày trước và không có pull request nào đang mở. Đang mởpriority: p2 type: bug
googlemaps/react-native-navigation-sdk#607 · 1 bình luận · 2 người được giao ·
Maintainer thường phản hồi trong vòng 5 ngày
Tất cả issue của googlemaps/react-native-navigation-sdk
Issue tương tự
-
pending close triaging
Độ khó 1/5 1-3 giờ Mức phù hợp với người mới 74/100
anomalyco/opencode#63090 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
ai-driven-qa bug claude Cosmetic
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 74/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
Maintainer thường phản hồi trong vòng 1 ngày
-
ai-driven-qa bug claude Minor
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
linagora/twake-mail-admin#609 ·
Maintainer thường phản hồi trong vòng 1 ngày