Skip to content

Retries & Timeouts

ResourceLoader.js has built-in support for retrying failed loads and aborting slow ones. These features work together to make resource loading resilient without any extra code on your part.

Every resource load has a timeout. If the resource does not finish loading within the timeout period, the load is aborted and treated as a failure.

Default timeout: 10,000 ms (10 seconds)

ResourceLoader.include(['https://api.example.com/data.json'], {
timeout: 5000, // 5 seconds
});

When loading multiple resources, each one gets its own independent timeout clock. One slow resource does not affect the timeout for the others.

ResourceLoader.include([
'https://cdn.example.com/fast.css', // Has its own 5-second clock
'https://slow-api.example.com/data.json', // Has its own 5-second clock
], {
timeout: 5000,
});

When a timeout occurs, the resource fails with error.type === 'timeout':

ResourceLoader.include(['https://slow-server.example.com/large.js'], {
timeout: 3000,
onError: (error, url) => {
if (error.type === 'timeout') {
console.warn(`${url} took too long — load aborted after 3s`);
}
},
});

By default, failed loads are not retried (retries: 0). Set retries to a positive integer to automatically retry on failure.

ResourceLoader.include(['https://flaky-api.example.com/config.json'], {
retries: 3, // Try up to 4 times total (1 initial + 3 retries)
});

Use retryDelay (in milliseconds) to add a pause between retry attempts. This prevents hammering a server that is temporarily overloaded:

ResourceLoader.include(['https://flaky-api.example.com/config.json'], {
retries: 3,
retryDelay: 2000, // Wait 2 seconds between attempts
});

Each retry attempt is independent. If attempt 1 fails, retryDelay is waited, then attempt 2 starts. Here is the flow:

Attempt 1 → FAIL
└─ wait 2000ms
Attempt 2 → FAIL
└─ wait 2000ms
Attempt 3 → FAIL
└─ wait 2000ms
Attempt 4 → FAIL → reject with error
Attempt 1 → FAIL
└─ wait 2000ms
Attempt 2 → SUCCESS → resolve
ResourceLoader.include(['https://flaky-api.example.com/data.json'], {
timeout: 8000,
retries: 3,
retryDelay: 1500,
onSuccess: (data) => {
console.log('Loaded successfully:', data);
},
onError: (error, url) => {
// This fires after ALL retries are exhausted
console.error(`All attempts failed for ${url}:`, error.type);
},
}).catch((error) => {
// Promise rejects after all retries fail
showErrorUI('Could not load required data. Please refresh.');
});

Error TypeRetried?Reason
networkYesCould be a transient network hiccup
timeoutYesServer may have been temporarily slow
abortNoUser or code explicitly cancelled the load
unsupportedNoThe file type will never be supported — retrying is pointless

  • Unsupported file types: The error is deterministic — retries waste time.
  • Authentication errors (HTTP 401/403): Retrying won’t fix an auth failure — handle it explicitly.
  • Very large files: Retrying a 50 MB download three times can be costly on mobile. Consider increasing timeout instead.
  • User-initiated cancellations: If the user clicks “Cancel”, don’t retry — they made an intentional choice.

ScenariotimeoutretriesretryDelay
CDN static assets (fast)100000
CDN static assets (production)1000011000
REST API (stable)800011000
REST API (flaky/external)800032000
Large binary file3000013000
Real-time data (must be fresh)30000