rsnext/packages/next/client/request-idle-callback.ts
Joe Haddad 0d5bf65feb
Replace page loader with new route loader (#19006)
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
2020-11-11 18:13:16 +00:00

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