0d5bf65feb
This pull request completely replaces our old page loader with a brand new route loader. Our existing comprehensive test suite means I did not need to add a bunch of tests. I did add them where behavior was added or fixed. Summary of the changes: - Eagerly evaluates prefetched pages in browser idle time (speeds up transitions) - Router is **no longer frozen** indefinitely if the Build Manifest never arrives - Router is **no longer frozen** indefinitely if a page fails to bootstrap - New `withFuture` utility instead of ad-hoc deduping per resource - Prefetching is now delayed until browser idle time to not impact TTI - Browsers without `prefetch` now fall back to eager evaluation instead of using `preload` - We're now ready to serve non-static assets **with `no-store` without breaking prefetching** - **Application can now hydrate without fetching CSS assets—this is a huge performance win that was previously blocking hydration** --- The minor size increase here is unfortunate, but we have to incur it for correctness. --- Fixes #18389 Fixes #18642
33 lines
828 B
TypeScript
33 lines
828 B
TypeScript
type RequestIdleCallbackHandle = any
|
|
type RequestIdleCallbackOptions = {
|
|
timeout: number
|
|
}
|
|
type RequestIdleCallbackDeadline = {
|
|
readonly didTimeout: boolean
|
|
timeRemaining: () => number
|
|
}
|
|
|
|
declare global {
|
|
interface Window {
|
|
requestIdleCallback: (
|
|
callback: (deadline: RequestIdleCallbackDeadline) => void,
|
|
opts?: RequestIdleCallbackOptions
|
|
) => RequestIdleCallbackHandle
|
|
}
|
|
}
|
|
|
|
const requestIdleCallback =
|
|
(typeof self !== 'undefined' && self.requestIdleCallback) ||
|
|
function (cb: (deadline: RequestIdleCallbackDeadline) => void) {
|
|
let start = Date.now()
|
|
return setTimeout(function () {
|
|
cb({
|
|
didTimeout: false,
|
|
timeRemaining: function () {
|
|
return Math.max(0, 50 - (Date.now() - start))
|
|
},
|
|
})
|
|
}, 1)
|
|
}
|
|
|
|
export default requestIdleCallback
|