5 / 66 · 09 Mobile & Cross-Platform Testing · The Device Fragmentation Reality← prev⊞ allnext →☰ Read as one page
1.5Network Condition Variability
Network conditions are the most underestimated fragmentation dimension. A feature that works perfectly on WiFi may be unusable on a congested 3G connection.
| Condition | Typical Latency | Typical Bandwidth | Where It Occurs |
|---|---|---|---|
| WiFi (good) | 5-20ms | 50-500 Mbps | Home, office |
| WiFi (congested) | 50-200ms | 1-10 Mbps | Coffee shops, airports |
| 5G | 10-30ms | 100-500 Mbps | Urban areas |
| 4G/LTE | 30-50ms | 10-50 Mbps | Suburban, most areas |
| 3G | 100-500ms | 0.5-5 Mbps | Rural, developing markets |
| 2G/Edge | 300-1000ms | 0.05-0.2 Mbps | Remote areas, tunnels |
| Offline | Infinite | 0 | Elevators, subways, airplane mode |
Testing Network Conditions
// Playwright: emulate network conditions
import { test } from '@playwright/test';
const networkProfiles = {
'4g': { download: 4_000_000, upload: 3_000_000, latency: 40 },
'3g': { download: 750_000, upload: 250_000, latency: 100 },
'slow3g': { download: 500_000, upload: 250_000, latency: 300 },
'offline': { download: 0, upload: 0, latency: 0 },
};
for (const [name, profile] of Object.entries(networkProfiles)) {
test(`app loads within budget on ${name}`, async ({ page, context }) => {
const cdp = await context.newCDPSession(page);
await cdp.send('Network.emulateNetworkConditions', {
offline: profile.download === 0,
downloadThroughput: profile.download / 8,
uploadThroughput: profile.upload / 8,
latency: profile.latency,
});
const start = Date.now();
await page.goto('/');
const loadTime = Date.now() - start;
// Set budget per network condition
const budgets: Record<string, number> = {
'4g': 3000,
'3g': 8000,
'slow3g': 15000,
};
if (budgets[name]) {
expect(loadTime).toBeLessThan(budgets[name]);
}
});
}