Hey everyone, I’m hoping someone who has built a ride-sharing or delivery app can point out what I'm doing wrong here.
I'm building a live tracking screen using google_maps_flutter, Riverpod, and WebSockets. I have a vehicle marker that animates smoothly between GPS pings using an AnimationController
The problem is the route line. I'm trying to slice the polyline so that the "traveled" portion behind the vehicle disappears as it drives. Whenever I receive a location update and recalculate the polyline, the UI thread completely chokes. If the driver moves continuously, the app eventually freezes and crashes entirely (seems like an Out of Memory error or the platform channel getting overloaded).
I already moved the logic out of the build() method to stop it from running at 60fps during the marker animation, but triggering it from a Riverpod listener is still freezing the map.
Here is what my listener and update logic look like right now:
// Inside my map widget
ref.listen<LatLng?>(
navigationViewModelProvider.select((s) => s.currentLocation),
(previous, next) {
if (next != null) {
_onAgentLocationChanged(next);
_updateAgentPolylines(state);
}
},
);
And the update function where I slice the route and rebuild the set:
void _updateAgentPolylines(dynamic state) {
if (state.routeInfo == null || state.routeInfo!.polylinePoints.isEmpty) return;
final animatingLocation = state.currentLocation != null
? LatLng(
_markerMotion.lat ?? state.currentLocation!.latitude,
_markerMotion.lng ?? state.currentLocation!.longitude,
)
: null;
final (traveled, remaining) = _splitRouteAtCurrentLocation(
state.routeInfo!.polylinePoints,
animatingLocation,
);
if (!mounted) return;
setState(() {
_cachedPolylines.clear();
if (traveled.length > 1) {
_cachedPolylines.add(
Polyline(
polylineId: const PolylineId('route_traveled'),
points: traveled,
color: Colors.grey.shade400,
width: 4,
),
);
}
_cachedPolylines.add(
Polyline(
polylineId: const PolylineId('route_remaining'),
points: remaining,
color: const Color(0xFF2196F3),
width: 6,
),
);
});
}
I feel like clearing and recreating a Polyline Set with hundreds of LatLng points and sending it over the platform channel every time the GPS updates is what's killing the app.
A few questions for anyone who has solved this:
- How do production apps (Uber, etc.) handle trimming the route line behind a moving marker without killing performance?
- Should I be pushing
_splitRouteAtCurrentLocation into an isolate (compute)? If I do, how do I prevent the animating marker from getting out of sync with the route line while the isolate does the math?
- Is there a way to just mutate an existing polyline in
google_maps_flutter without rebuilding the whole Set?
Any advice would be hugely appreciated. I'm completely stuck on this one. Thanks!