forked from vercel/next.js
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Load
beforeInteractive
scripts properly without blocking hydration (v…
…ercel#41164) This PR ensures that for the app directory, `beforeInteractive`, `afterInteractive` and `lazyOnload` scripts via `next/script` are properly supported. For both `beforeInteractive` and `afterInteractive` scripts, a preload link tag needs to be injected by Float. For `beforeInteractive` scripts and Next.js' polyfills, they need to be manually executed in order before starting the Next.js' runtime, without blocking the downloading of HTML and other scripts. This PR doesn't include the `worker` type of scripts yet. Note: in this PR I changed the inlined flight data `__next_s` to `__next_f`, and use `__next_s` for scripts data, because I can't find a better name for `next/script` that is also short at the same time. ## Bug - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have a helpful link attached, see `contributing.md` ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [x] Integration tests added - [ ] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - [ ] Errors have a helpful link attached, see `contributing.md` ## Documentation / Examples - [ ] Make sure the linting passes by running `pnpm lint` - [ ] The "examples guidelines" are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md)
- Loading branch information
Showing
16 changed files
with
286 additions
and
62 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
/** | ||
* Before starting the Next.js runtime and requiring any module, we need to make | ||
* sure the following scripts are executed in the correct order: | ||
* - Polyfills | ||
* - next/script with `beforeInteractive` strategy | ||
*/ | ||
|
||
const version = process.env.__NEXT_VERSION | ||
|
||
window.next = { | ||
version, | ||
appDir: true, | ||
} | ||
|
||
function loadScriptsInSequence(scripts, hydrate) { | ||
if (!scripts || !scripts.length) { | ||
return hydrate() | ||
} | ||
|
||
return scripts | ||
.reduce((promise, [src, props]) => { | ||
return promise.then(() => { | ||
return new Promise((resolve, reject) => { | ||
const el = document.createElement('script') | ||
|
||
if (props) { | ||
for (const key in props) { | ||
if (key !== 'children') { | ||
el.setAttribute(key, props[key]) | ||
} | ||
} | ||
} | ||
|
||
if (src) { | ||
el.src = src | ||
el.onload = resolve | ||
el.onerror = reject | ||
} else if (props) { | ||
el.innerHTML = props.children | ||
setTimeout(resolve) | ||
} | ||
|
||
document.head.appendChild(el) | ||
}) | ||
}) | ||
}, Promise.resolve()) | ||
.then(() => { | ||
hydrate() | ||
}) | ||
.catch((err) => { | ||
console.error(err) | ||
// Still try to hydrate even if there's an error. | ||
hydrate() | ||
}) | ||
} | ||
|
||
export function appBootstrap(callback) { | ||
loadScriptsInSequence(self.__next_s, () => { | ||
callback() | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,10 @@ | ||
import { hydrate, version } from './app-index' | ||
|
||
// TODO-APP: hydration warning | ||
|
||
window.next = { | ||
version, | ||
appDir: true, | ||
} | ||
import { appBootstrap } from './app-bootstrap' | ||
|
||
hydrate() | ||
appBootstrap(() => { | ||
const { hydrate } = require('./app-index') | ||
hydrate() | ||
}) | ||
|
||
// TODO-APP: build indicator |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,10 @@ | ||
import { hydrate, version } from './app-index' | ||
import { appBootstrap } from './app-bootstrap' | ||
|
||
// Include app-router and layout-router in the main chunk | ||
import 'next/dist/client/components/app-router.client.js' | ||
import 'next/dist/client/components/layout-router.client.js' | ||
appBootstrap(() => { | ||
// Include app-router and layout-router in the main chunk | ||
import('next/dist/client/components/app-router.client.js') | ||
import('next/dist/client/components/layout-router.client.js') | ||
|
||
window.next = { | ||
version, | ||
appDir: true, | ||
} | ||
|
||
hydrate() | ||
const { hydrate } = require('./app-index') | ||
hydrate() | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.