Every mobile developer has encountered this frustration when building infinite scroll feeds in React Native:
The user scrolls down a product list or social feed. As they reach the bottom of page 1, onEndReached triggers to fetch page 2.
Over a mobile 4G or 5G connection:
- The API request takes 450ms to 900ms to resolve.
- The user hits the bottom of the list and stares at a blank space or loading spinner.
- The scroll momentum stutters, and the feed feels sluggish.
Here is why client-side mobile pagination struggles on cellular networks, and how handling cursor pagination at the edge eliminates scroll lag.
The Cellular Latency Problem in Mobile Apps
Mobile devices do not have continuous high-speed fiber connections. Over cellular networks (4G/LTE/5G), establishing network handshakes and traversing physical distance to a central cloud server introduces high latency:
Mobile Phone (Cellular Tower)
│ (Radio access network latency: 60ms–150ms)
▼
Regional Internet Routing (2-4 hops)
│ (Transit RTT: 80ms–200ms)
▼
Origin Data Center (us-east-1)
│
├── App Server JSON Serialization (40ms)
└── Database Offset / Cursor Query (80ms)
│
▼
Total Request Time: 260ms – 570ms
When a user scrolls quickly, the device cannot fetch pages fast enough to keep up with the scroll speed.
3 Fixes for Instant Mobile Pagination
1. Cursor Normalization at the Edge
Offset pagination (?offset=40&limit=20) is slow on SQL databases because the database has to scan and discard 40 rows before returning the result.
Use cursor-based pagination with indexed keys (?cursor=item_9281&limit=20), and route the mobile app's API base URL through an edge proxy.
// React Native API Client
const API_BASE_URL = 'https://api.your-app.com'; // Routed via CNAME to ApexCache
export async function fetchFeedPage(cursor?: string) {
const url = cursor
? `${API_BASE_URL}/v1/feed?cursor=${cursor}&limit=20`
: `${API_BASE_URL}/v1/feed?limit=20`;
const res = await fetch(url, {
headers: { 'Accept': 'application/json' }
});
return res.json();
}
2. Edge-Side Stale-While-Revalidate (SWR)
Because page 1 and page 2 are requested frequently by all active users, the edge proxy caches the serialized JSON responses in memory at points of presence close to the user.
When the mobile app requests GET /v1/feed?cursor=item_9281:
- The nearest edge node returns the cached JSON in under 14 milliseconds.
- The network round-trip finishes before the user reaches the end of the current viewport.
- The FlatList renders the next 20 items seamlessly without any visible loading spinner.
3. Pre-Fetching Next Page During Scroll
Combine edge caching with intelligent client-side prefetching.
Instead of waiting for onEndReached (which fires when the user is already at the bottom), trigger a background pre-fetch when the user scrolls past the 70% threshold:
import React, { useState, useCallback } from 'react';
import { FlatList, View, Text, ActivityIndicator } from 'react-native';
export const ProductFeed = () => {
const [items, setItems] = useState([]);
const [nextCursor, setNextCursor] = useState(null);
const [loading, setLoading] = useState(false);
const loadMore = useCallback(async () => {
if (loading || !nextCursor) return;
setLoading(true);
try {
const data = await fetchFeedPage(nextCursor);
setItems(prev => [...prev, ...data.items]);
setNextCursor(data.nextCursor);
} finally {
setLoading(false);
}
}, [loading, nextCursor]);
return (
<FlatList
data={items}
keyExtractor={(item) => item.id}
renderItem={({ item }) => <ProductCard item={item} />}
onEndReached={loadMore}
onEndReachedThreshold={0.5} // Trigger early when half a screen away
ListFooterComponent={loading ? <ActivityIndicator size="small" /> : null}
/>
);
};
Production Metrics
| Metric | Central Cloud Origin | Edge Proxy (ApexCache) |
|---|---|---|
| P50 Page Fetch Latency | 420ms | 12ms |
| P99 Page Fetch Latency | 1,280ms | 18ms |
| Scroll Stutters / Janks | Frequent on fast scrolls | Zero visible lag |
| Database Read IOPS | 100% load | 8% load (92% offload) |
Conclusion
Mobile pagination lag is primarily a network distance and database scan problem.
By adopting cursor-based queries and offloading paginated reads to a compiled edge proxy, mobile feeds load instantly across 4G and 5G connections without overloading your database.
- Documentation on Mobile API Caching: getapexcache.com/docs/integrate-mobile
Top comments (0)