TL;DR
fetch-network-simulator — это инструмент для эмуляции нестабильного сетевого окружения прямо в dev-среде. Перехватывает fetch(), подмешивает латентность, потерю пакетов, ретраи, race conditions и bandwidth throttling. Незаменим для отлова timing-dependent багов, которые не проявляются при идеальном соединении.
Введение: зачем симулировать проблемы сети?
В 2024 году фронтенд-разработчики столкнулись с парадоксом:
- Локально приложение летает
- На продовых CDN — перформанс на уровне
- Но у 3% юзеров — лаги, фризы и критические ошибки
Проблема в нелинейности сетевых условий. Традиционные моки и стабы не покрывают:
- Flaky-connection с intermittent packet loss
- Race conditions при конкурентных запросах
- Stale responses из-за кеширования промежуточных прокси
Основная часть: как работает симулятор
Перехват fetch()
Ядро системы — Proxy API для перехвата нативных запросов:
const originalFetch = window.fetch;
window.fetch = async (...args) => {
if (shouldSimulateNetwork()) {
return applyNetworkChaos(...args);
}
return originalFetch(...args);
};
Конфигурируемые параметры
NetworkSimulator.configure({
latency: { min: 100, max: 2000 }, // ms
packetLoss: 0.05, // 5% запросов теряются
concurrencyLimit: 6, // HTTP/1.1-like limit
retryPolicy: {
maxAttempts: 3,
backoff: 'exponential'
}
});
Эмуляция race conditions
Симулятор вводит искусственную недетерминированность:
async function applyRaceConditions(responsePromise) {
await randomDelay();
if (Math.random() < config.raceProbability) {
return simulateStaleResponse();
}
return responsePromise;
}
Практическое применение
Тестирование Skeleton UI
Пример проверки загрузочных состояний:
describe('ProfilePage loading states', () => {
beforeAll(() => {
NetworkSimulator.configure({ latency: { min: 800, max: 1500 } });
});
it('shows skeleton for at least 500ms', async () => {
const { queryByTestId } = render(<ProfilePage />);
expect(queryByTestId('skeleton')).toBeInTheDocument();
await act(async () => {
await new Promise(r => setTimeout(r, 500));
});
expect(queryByTestId('skeleton')).toBeInTheDocument();
});
});
Воспроизведение багов с конкурентными запросами
// Эмулируем HTTP/1.1 pipeline head-of-line blocking
NetworkSimulator.configure({
concurrencyLimit: 2,
requestQueue: 'fifo'
});
// Теперь можно отловить deadlock в цепочке запросов:
fetch('/api/user');
fetch('/api/posts');
fetch('/api/comments'); // Этот запрос заблокируется
Заключение
fetch-network-simulator закрывает критический gap в фронтенд-тестировании — невозможность воспроизвести сетевые аномалии в контролируемой среде. Инструмент особенно полезен для:
- Разработки resilient-архитектур
- Тестирования Progressive Enhancement стратегий
- Валидации UX в экстремальных условиях
Для глубокой интеграции рекомендую комбинировать с:
- Chrome DevTools Throttling
- WebPageTest custom profiles
- Собственными метриками RUM (Real User Monitoring)
Просто помните: если ваш код работает под fetch-network-simulator, он с большой вероятностью выживет и в диком проде.
Источник: https://github.com/thisiskps/fetch-network-simulator