WellAlly Logo
WellAlly康心伴
Development

Fixing the Battery Drain: A React Native Location-Tracking App Case Study

A deep-dive case study on how we slashed battery drain by 60% in our React Native fitness app. Learn technical strategies for adaptive location accuracy, background processing, and batching API calls to fix performance issues and boost app ratings.

W
2025-12-20
9 min read

Have you ever built a feature-rich app, only to see it get hammered in the reviews with comments like "Great app, but it kills my battery!"? This is a common nightmare for developers of location-aware applications. Our team at "FitTrack," a fictional React Native app for tracking runs and bike rides, faced this exact crisis. We had a sleek UI and great features, but our app was a notorious battery vampire, leading to a dismal 2.1-star rating.

This article is a case study of how we turned things around. We'll walk you through the technical strategies we used to slash battery consumption by over 60%, transforming our user feedback from complaints to praise. We'll cover the nitty-gritty of location accuracy, background processing, and network optimization.

Prerequisites: You should have a solid understanding of React Native, including state management and working with third-party libraries. Familiarity with JavaScript (ES6+) is a must.

Why this matters to developers: In the competitive world of mobile apps, poor battery performance is a deal-breaker. Users will uninstall an app that drains their phone, no matter how useful it is. By mastering these optimization techniques, you can deliver a superior user experience, boost your app's ratings, and retain more users.

Understanding the Problem

Initially, FitTrack was a textbook example of what not to do. We were polling for the user's location with the highest possible accuracy every few seconds, even when the app was in the background. This continuous use of the GPS radio was the primary culprit behind the excessive battery drain.

Here's a breakdown of our initial, naive approach:

  • Constant High-Accuracy Polling: We used a simple setInterval to fetch GPS coordinates, keeping the GPS chip active at all times during a workout.
  • Aggressive Background Updates: Our background tasks were not optimized, leading to frequent and unnecessary wake-ups of the device.
  • Chatty API Calls: Every single location update was immediately sent to our server, resulting in a constant stream of network requests, another major source of battery drain.

The result? A 30-minute run could consume over 20% of a user's battery. The negative reviews were piling up, and we knew we had to act fast.

Prerequisites

Before we dive into the solutions, here's what you'll need to follow along:

  • Node.js and npm/yarn installed
  • A React Native development environment set up for both iOS and Android
  • We'll be using the react-native-background-geolocation library, as it offers sophisticated, battery-saving features out of the box.

Setup Commands:

code
npx react-native init FitTrackApp
cd FitTrackApp
npm install @mauron85/react-native-background-geolocation
Code collapsed

You will also need to follow the library's installation instructions for configuring permissions on both iOS and Android, which is crucial for location tracking.

Step 1: Implementing Adaptive Location Accuracy

Our first major breakthrough was realizing that we didn't always need pinpoint accuracy. A user standing still at a traffic light doesn't need the same location precision as someone sprinting down a trail.

What we're doing

We decided to dynamically adjust the location tracking settings based on the user's activity (e.g., stationary, walking, running). The react-native-background-geolocation library has built-in activity recognition, which made this much easier.

Implementation

code
// src/services/LocationService.js
import BackgroundGeolocation from '@mauron85/react-native-background-geolocation';

const configureTracker = () => {
  BackgroundGeolocation.configure({
    desiredAccuracy: BackgroundGeolocation.HIGH_ACCURACY,
    stationaryRadius: 25, // When stationary, report location every 25 meters
    distanceFilter: 10,   // Report location every 10 meters
    debug: false,
    startOnBoot: false,
    stopOnTerminate: true,
    locationProvider: BackgroundGeolocation.ACTIVITY_PROVIDER,
    interval: 10000, // In milliseconds
    fastestInterval: 5000,
    activitiesInterval: 10000,
    stopOnStillActivity: false,
  });

  BackgroundGeolocation.on('location', (location) => {
    // Handle location updates
    console.log('[LOCATION]', location);
  });

  BackgroundGeolocation.start();
};

export { configureTracker };
Code collapsed

How it works

The key here is the locationProvider: BackgroundGeolocation.ACTIVITY_PROVIDER. This tells the library to use a combination of GPS, Wi-Fi, and cell tower data, and to adjust its power consumption based on detected motion. We also use stationaryRadius to create a virtual geofence when the user is not moving, preventing unnecessary GPS polling.

Common pitfalls

A common mistake is to only rely on desiredAccuracy. You must also configure distanceFilter and stationaryRadius to achieve significant battery savings. Without these, even with a lower accuracy setting, the GPS can still be polled too frequently.

Step 2: Smarter Background Processing with Foreground Services

On Android, background processes can be killed by the OS to save power. For a fitness app, this is a disaster, as it would mean losing track of a user's run. The solution is to use a Foreground Service, which tells the OS that the app is performing a user-initiated task and should not be terminated.

What we're doing

We'll configure our location tracking to run as a foreground service on Android. This will display a persistent notification to the user, letting them know that the app is actively tracking their location, which is also a good practice for transparency.

Implementation

In your react-native-background-geolocation configuration, add the following:

code
// src/services/LocationService.js (additions to the config)
BackgroundGeolocation.configure({
  // ... other settings
  startForeground: true, // This is the key for Android
  notificationTitle: "FitTrack is active",
  notificationText: "Tracking your workout",
});
Code collapsed

How it works

Setting startForeground: true promotes the background location service to a foreground service on Android. This gives it higher priority and makes it much less likely to be killed by the system. For iOS, the library handles background execution through the appropriate background modes defined in your app's capabilities.

Common pitfalls

Forgetting to request the necessary background location permissions is a common issue. On newer Android and iOS versions, you need to explicitly ask the user for permission to access their location "all the time" for this to work reliably.

Step 3: Batching API Calls to Reduce Network Drain

Our final area for optimization was our network usage. As mentioned, we were sending every location point to our server in real-time. This kept the phone's radio active, which is a huge battery drain.

What we're doing

We implemented a system to batch location updates. Instead of sending each point individually, we collect a series of points in the app and send them to the server in a single request every minute or so.

Implementation

code
// src/services/LocationService.js
let locationBuffer = [];
const BATCH_SIZE = 20; // Send updates after collecting 20 points
const BATCH_TIMEOUT = 60000; // Or send updates every 60 seconds

const sendLocationBatch = async () => {
  if (locationBuffer.length === 0) return;

  const batch = [...locationBuffer];
  locationBuffer = [];

  try {
    await fetch('https://api.fittrack.com/track', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ locations: batch }),
    });
  } catch (error) {
    console.error("Failed to send location batch", error);
    // Implement a retry mechanism or store locally for later
    locationBuffer = [...batch, ...locationBuffer];
  }
};

// Set up a timer to send batches periodically
setInterval(sendLocationBatch, BATCH_TIMEOUT);

BackgroundGeolocation.on('location', (location) => {
  locationBuffer.push({
    latitude: location.latitude,
    longitude: location.longitude,
    timestamp: location.time,
  });

  if (locationBuffer.length >= BATCH_SIZE) {
    sendLocationBatch();
  }
});
Code collapsed

How it works

We maintain an array, locationBuffer, to store location data. We then use a combination of a batch size limit and a timer to decide when to send the data. This dramatically reduces the number of network requests and allows the phone's radio to remain in a low-power state for longer periods.

Putting It All Together

By combining these three strategies—adaptive accuracy, foreground services, and API batching—we achieved a dramatic reduction in battery consumption. Our internal tests showed that a 30-minute run now only consumed about 7-8% of the battery, a huge improvement from the original 20%+.

After releasing the update, the results were immediate. Our 1-star reviews about battery drain turned into 5-star raves about the app's performance and reliability. Our app's rating climbed from 2.1 to 4.7 stars within a month.

Conclusion

Optimizing a location-tracking app for battery life is a balancing act between functionality and efficiency. By moving from a naive, brute-force approach to an intelligent, adaptive one, we were able to save our app from the brink of failure.

Our key achievements were:

  • Reduced battery drain by over 60%.
  • Improved the reliability of background tracking.
  • Significantly boosted our app store ratings and user sentiment.

We encourage you to analyze your own location-aware apps. Are you making any of the same mistakes we were? By implementing these strategies, you can provide a much better experience for your users.

Resources

#

Article Tags

reactnativemobileperformanceandroidios
W

WellAlly's core development team, comprised of healthcare professionals, software engineers, and UX designers committed to revolutionizing digital health management.

Expertise

Healthcare TechnologySoftware DevelopmentUser ExperienceAI & Machine Learning

Found this article helpful?

Try KangXinBan and start your health management journey

© 2024 康心伴 WellAlly · Professional Health Management