New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes to the beforeInteractive strategy to make it work for streaming #31936
Conversation
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
packages/eslint-plugin-next/lib/rules/no-script-bi-outside-document.js
Outdated
Show resolved
Hide resolved
@@ -0,0 +1,51 @@ | |||
const path = require('path') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In addition to an ESLint warning, would be good to have a runtime console warning since some people don't use ESLint and this will actually break once streaming is added.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@janicklas-ralph Document
and App
are rendered in separate React trees, so I think you could just reuse the context to determine if we're rendering Document
or not and warn appropriately
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1. I think it's OK to put the console warning in a separate PR though (I'm good with merging this one with just the ESLint warning and docs)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for doing this! Most of my comments are documentation-related 🙏
docs/basic-features/script.md
Outdated
|
||
- `beforeInteractive`: Load before the page is interactive | ||
- `beforeInteractive`: Load scripts required by the entire site before the page is interactive |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- `beforeInteractive`: Load scripts required by the entire site before the page is interactive | |
- `beforeInteractive`: Load script when any page in the application is loaded and before it becomes interactive |
docs/basic-features/script.md
Outdated
|
||
- `beforeInteractive`: Load before the page is interactive | ||
- `beforeInteractive`: Load scripts required by the entire site before the page is interactive | ||
- `beforePageRender`: Load scripts required by a particular page before the page is interactive |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- `beforePageRender`: Load scripts required by a particular page before the page is interactive | |
- `beforePageRender`: Load script when for a single page before it becomes interactive |
docs/basic-features/script.md
Outdated
- `afterInteractive`: (**default**): Load immediately after the page becomes interactive | ||
- `lazyOnload`: Load during idle time | ||
|
||
#### beforeInteractive | ||
|
||
Scripts that load with the `beforeInteractive` strategy are injected into the initial HTML from the server and run before self-bundled JavaScript is executed. This strategy should be used for any critical scripts that need to be fetched and executed before the page is interactive. | ||
Scripts that load with the `beforeInteractive` strategy are injected into the initial HTML from the server and run before self-bundled JavaScript is executed. This strategy should be used for any critical scripts that need to be fetched and executed before the page is interactive. This strategy only works inside **\_document.js** and is designed to load scripts that is needed by the entire site. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This strategy only works inside **\_document.js** and is designed to load scripts that is needed by the entire site
Which of the following correct?
- Script will only load once on a page reload (SSR) and not during page transitions (CSR), but will load when any page is reloaded
- Script will load during page reload (SSR) and during client side transitions
I assume it's the first option, and if so - can we clarify that a bit here? Something along the lines of:
Scripts that load with the `beforeInteractive` strategy are injected into the initial HTML from the server and run before self-bundled JavaScript is executed. This strategy should be used for any critical scripts that need to be fetched and executed before the page is interactive. This strategy only works inside **\_document.js** and is designed to load scripts that is needed by the entire site. | |
Scripts that load with the `beforeInteractive` strategy are injected into the initial HTML from the server and run before self-bundled JavaScript is executed. This strategy should be used for any critical scripts that need to be fetched and executed before any page becomes interactive. This strategy only works inside **\_document.js** and is designed to load scripts that is needed by the entire site (i.e. the script will load when any page in the application has been loaded server-side). |
docs/basic-features/script.md
Outdated
<Main /> | ||
<NextScript /> | ||
<Script | ||
id="scriptBeforeInteractive" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the id
here necessary? If not, could we remove it to keep the code snippets as short as possible
docs/basic-features/script.md
Outdated
<NextScript /> | ||
<Script | ||
id="scriptBeforeInteractive" | ||
src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js?a=scriptBeforeInteractive" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm confused about the a=scriptBeforeInteractive
queryparam here. Was it included for any particular reason? If not, can we remove it so folks don't get confused thinking that it's a requirement to have? :)
src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js?a=scriptBeforeInteractive" | |
src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js" |
docs/basic-features/script.md
Outdated
``` | ||
|
||
Examples of scripts that should be loaded as soon as possible with this strategy include: | ||
|
||
- Bot detectors | ||
- Cookie consent managers | ||
|
||
#### beforePageRender | ||
|
||
Scripts that load with the `beforePageRender` strategy are injected into the initial HTML from the server and run before self-bundled JavaScript is executed. This strategy is similar to `beforeInteractive` but is designed for scripts that are needed by a page and not the entire site. Syntax for adding the script is as shown below. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similarly here, can we clarify that this Script will load only for a page that it has been used in.
Scripts that load with the `beforePageRender` strategy are injected into the initial HTML from the server and run before self-bundled JavaScript is executed. This strategy is similar to `beforeInteractive` but is designed for scripts that are needed by a page and not the entire site. Syntax for adding the script is as shown below. | |
Scripts that load with the `beforePageRender` strategy are injected into the initial HTML from the server and run before self-bundled JavaScript is executed. This strategy is similar to `beforeInteractive` but is designed for scripts that are needed by a page and not the entire site (i.e. this script will load only when the page that uses it is loaded server-side) |
docs/basic-features/script.md
Outdated
Page.scriptLoader = () => { | ||
return ( | ||
<Script | ||
id="scriptBeforePageRender" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similarly here, can we remove the unnecessary id?
id="scriptBeforePageRender" |
docs/basic-features/script.md
Outdated
return ( | ||
<Script | ||
id="scriptBeforePageRender" | ||
src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js?a=scriptBeforePageRender" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similarly here, can we remove the unnecessary query param?
src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js?a=scriptBeforePageRender" | |
src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js" |
@@ -20,6 +20,7 @@ module.exports = { | |||
'no-duplicate-head': require('./rules/no-duplicate-head'), | |||
'inline-script-id': require('./rules/inline-script-id'), | |||
'next-script-for-ga': require('./rules/next-script-for-ga'), | |||
'no-script-bi-outside-document': require('./rules/no-script-bi-outside-document'), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit (feel free to ignore): I think it would be nicer to not shorten beforeInteractive to bi
in the naming here. Maybe something like no-before-interactive-script-outside-doument
?
@@ -39,12 +40,13 @@ module.exports = { | |||
'@next/next/next-script-for-ga': 1, | |||
'@next/next/no-document-import-in-page': 2, | |||
'@next/next/no-head-import-in-document': 2, | |||
'@next/next/no-script-in-document': 2, | |||
'@next/next/no-script-in-document': 0, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we're turning off this rule entirely, we should probably just delete it completely (unless you think there's a reason why folks would like to turn it on?)
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Failing test suitesCommit: 19f9ae1
Expand output● experimental.nextScriptWorkers: true with required Partytown dependency › Worker scripts are modified by Partytown to execute on a worker thread
Read more about building and testing Next.js in contributing.md. |
Failing test suitesCommit: 19f9ae1
Expand output● Next.js Script - Primary Strategies › priority beforeInteractive
● Next.js Script - Primary Strategies › priority beforeInteractive on navigate
Read more about building and testing Next.js in contributing.md. |
Failing test suitesCommit: 19f9ae1
Expand output● experimental.nextScriptWorkers: true with required Partytown dependency › Worker scripts are modified by Partytown to execute on a worker thread
Read more about building and testing Next.js in contributing.md. |
Stats from current PRDefault Build (Increase detected
|
vercel/next.js canary | janicklas-ralph/next.js script-update | Change | |
---|---|---|---|
buildDuration | 17.9s | 17.8s | -165ms |
buildDurationCached | 7.2s | 6.9s | -319ms |
nodeModulesSize | 484 MB | 484 MB |
Page Load Tests Overall increase ✓
vercel/next.js canary | janicklas-ralph/next.js script-update | Change | |
---|---|---|---|
/ failed reqs | 0 | 0 | ✓ |
/ total time (seconds) | 3.786 | 3.744 | -0.04 |
/ avg req/sec | 660.33 | 667.71 | +7.38 |
/error-in-render failed reqs | 0 | 0 | ✓ |
/error-in-render total time (seconds) | 1.635 | 1.602 | -0.03 |
/error-in-render avg req/sec | 1528.95 | 1560.9 | +31.95 |
Client Bundles (main, webpack) Overall increase ⚠️
vercel/next.js canary | janicklas-ralph/next.js script-update | Change | |
---|---|---|---|
925.HASH.js gzip | 179 B | 179 B | ✓ |
framework-HASH.js gzip | 42 kB | 42 kB | ✓ |
main-HASH.js gzip | 28 kB | 28.2 kB | |
webpack-HASH.js gzip | 1.44 kB | 1.44 kB | ✓ |
Overall change | 71.7 kB | 71.9 kB |
Legacy Client Bundles (polyfills)
vercel/next.js canary | janicklas-ralph/next.js script-update | Change | |
---|---|---|---|
polyfills-HASH.js gzip | 31 kB | 31 kB | ✓ |
Overall change | 31 kB | 31 kB | ✓ |
Client Pages
vercel/next.js canary | janicklas-ralph/next.js script-update | Change | |
---|---|---|---|
_app-HASH.js gzip | 1.36 kB | 1.36 kB | ✓ |
_error-HASH.js gzip | 192 B | 192 B | ✓ |
amp-HASH.js gzip | 309 B | 309 B | ✓ |
css-HASH.js gzip | 327 B | 327 B | ✓ |
dynamic-HASH.js gzip | 3.05 kB | 3.05 kB | ✓ |
head-HASH.js gzip | 351 B | 351 B | ✓ |
hooks-HASH.js gzip | 920 B | 920 B | ✓ |
image-HASH.js gzip | 5.68 kB | 5.68 kB | ✓ |
index-HASH.js gzip | 263 B | 263 B | ✓ |
link-HASH.js gzip | 2.32 kB | 2.32 kB | ✓ |
routerDirect..HASH.js gzip | 320 B | 320 B | ✓ |
script-HASH.js gzip | 387 B | 387 B | ✓ |
withRouter-HASH.js gzip | 319 B | 319 B | ✓ |
85e02e95b279..7e3.css gzip | 107 B | 107 B | ✓ |
Overall change | 15.9 kB | 15.9 kB | ✓ |
Client Build Manifests
vercel/next.js canary | janicklas-ralph/next.js script-update | Change | |
---|---|---|---|
_buildManifest.js gzip | 460 B | 460 B | ✓ |
Overall change | 460 B | 460 B | ✓ |
Rendered Page Sizes Overall increase ⚠️
vercel/next.js canary | janicklas-ralph/next.js script-update | Change | |
---|---|---|---|
index.html gzip | 531 B | 532 B | |
link.html gzip | 545 B | 546 B | |
withRouter.html gzip | 525 B | 526 B | |
Overall change | 1.6 kB | 1.6 kB |
Diffs
Diff for main-HASH.js
@@ -790,9 +790,8 @@
if (false) {
}
if (initialData.scriptLoader) {
- initScriptLoader = __webpack_require__(
- 3573
- ) /* .initScriptLoader */.z;
+ initScriptLoader = __webpack_require__(3573)
+ .initScriptLoader;
initScriptLoader(initialData.scriptLoader);
}
pageLoader = new _pageLoader.default(
@@ -2826,7 +2825,6 @@
__webpack_require__
) {
"use strict";
- var __webpack_unused_export__;
function _arrayLikeToArray(arr, len) {
if (len == null || len > arr.length) len = arr.length;
@@ -2836,6 +2834,16 @@
function _arrayWithHoles(arr) {
if (Array.isArray(arr)) return arr;
}
+ function _arrayWithoutHoles(arr) {
+ if (Array.isArray(arr)) return _arrayLikeToArray(arr);
+ }
+ function _iterableToArray(iter) {
+ if (
+ (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null) ||
+ iter["@@iterator"] != null
+ )
+ return Array.from(iter);
+ }
function _iterableToArrayLimit(arr, i) {
var _i =
arr == null
@@ -2869,6 +2877,11 @@
"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."
);
}
+ function _nonIterableSpread() {
+ throw new TypeError(
+ "Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."
+ );
+ }
function _slicedToArray(arr, i) {
return (
_arrayWithHoles(arr) ||
@@ -2877,6 +2890,14 @@
_nonIterableRest()
);
}
+ function _toConsumableArray(arr) {
+ return (
+ _arrayWithoutHoles(arr) ||
+ _iterableToArray(arr) ||
+ _unsupportedIterableToArray(arr) ||
+ _nonIterableSpread()
+ );
+ }
function _unsupportedIterableToArray(o, minLen) {
if (!o) return;
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
@@ -2889,10 +2910,11 @@
)
return _arrayLikeToArray(o, minLen);
}
- __webpack_unused_export__ = {
+ Object.defineProperty(exports, "__esModule", {
value: true
- };
- exports.z = initScriptLoader;
+ });
+ exports.handleClientScriptLoad = handleClientScriptLoad;
+ exports.initScriptLoader = initScriptLoader;
exports["default"] = void 0;
var _react = _interopRequireWildcard(__webpack_require__(7294));
var _headManagerContext = __webpack_require__(4664);
@@ -3090,14 +3112,14 @@
function handleClientScriptLoad(props) {
var _strategy = props.strategy,
strategy = _strategy === void 0 ? "afterInteractive" : _strategy;
- if (strategy === "afterInteractive") {
- loadScript(props);
- } else if (strategy === "lazyOnload") {
+ if (strategy === "lazyOnload") {
window.addEventListener("load", function() {
(0, _requestIdleCallback).requestIdleCallback(function() {
return loadScript(props);
});
});
+ } else {
+ loadScript(props);
}
}
function loadLazyScript(props) {
@@ -3113,8 +3135,22 @@
});
}
}
+ function addBeforeInteractiveToCache() {
+ var scripts = _toConsumableArray(
+ document.querySelectorAll('[data-nscript="beforeInteractive"]')
+ ).concat(
+ _toConsumableArray(
+ document.querySelectorAll('[data-nscript="beforePageRender"]')
+ )
+ );
+ scripts.forEach(function(script) {
+ var cacheKey = script.id || script.getAttribute("src");
+ LoadCache.add(cacheKey);
+ });
+ }
function initScriptLoader(scriptLoaderItems) {
scriptLoaderItems.forEach(handleClientScriptLoad);
+ addBeforeInteractiveToCache();
}
function Script(props) {
var _src = props.src,
@@ -4342,6 +4378,7 @@
exports["default"] = void 0;
var _normalizeTrailingSlash = __webpack_require__(2700);
var _routeLoader = __webpack_require__(2497);
+ var _script = __webpack_require__(3573);
var _isError = _interopRequireWildcard(__webpack_require__(676));
var _denormalizePagePath = __webpack_require__(4522);
var _normalizeLocalePath = __webpack_require__(4769);
@@ -5011,6 +5048,8 @@
props,
__N_SSG,
__N_SSP,
+ component,
+ scripts,
destination,
parsedHref,
ref3,
@@ -5504,14 +5543,23 @@
(props = routeInfo.props),
(__N_SSG = routeInfo.__N_SSG),
(__N_SSP = routeInfo.__N_SSP);
+ component = routeInfo.Component;
+ if (component && component.scriptLoader) {
+ scripts = [].concat(component.scriptLoader());
+ scripts.forEach(function(script) {
+ (0, _script).handleClientScriptLoad(
+ script.props
+ );
+ });
+ }
if (!((__N_SSG || __N_SSP) && props)) {
- _ctx.next = 144;
+ _ctx.next = 146;
break;
}
if (
!(props.pageProps && props.pageProps.__N_REDIRECT)
) {
- _ctx.next = 129;
+ _ctx.next = 131;
break;
}
destination = props.pageProps.__N_REDIRECT;
@@ -5521,7 +5569,7 @@
props.pageProps.__N_REDIRECT_BASE_PATH !== false
)
) {
- _ctx.next = 127;
+ _ctx.next = 129;
break;
}
parsedHref = (0,
@@ -5541,31 +5589,31 @@
"return",
_this.change(method, newUrl, newAs, options)
);
- case 127:
+ case 129:
window.location.href = destination;
return _ctx.abrupt(
"return",
new Promise(function() {})
);
- case 129:
+ case 131:
nextState.isPreview = !!props.__N_PREVIEW;
if (!(props.notFound === SSG_DATA_NOT_FOUND)) {
- _ctx.next = 144;
+ _ctx.next = 146;
break;
}
- _ctx.prev = 132;
- _ctx.next = 135;
+ _ctx.prev = 134;
+ _ctx.next = 137;
return _this.fetchComponent("/404");
- case 135:
+ case 137:
notFoundRoute = "/404";
- _ctx.next = 141;
+ _ctx.next = 143;
break;
- case 138:
- _ctx.prev = 138;
- _ctx.t3 = _ctx["catch"](132);
+ case 140:
+ _ctx.prev = 140;
+ _ctx.t3 = _ctx["catch"](134);
notFoundRoute = "/_error";
- case 141:
- _ctx.next = 143;
+ case 143:
+ _ctx.next = 145;
return _this.getRouteInfo(
notFoundRoute,
notFoundRoute,
@@ -5578,9 +5626,9 @@
nextState.locale,
nextState.isPreview
);
- case 143:
+ case 145:
routeInfo = _ctx.sent;
- case 144:
+ case 146:
Router.events.emit(
"beforeHistoryChange",
as,
@@ -5618,7 +5666,7 @@
y: 0
}
: null;
- _ctx.next = 153;
+ _ctx.next = 155;
return _this
.set(
_objectSpread({}, nextState, {
@@ -5637,9 +5685,9 @@
if (e.cancelled) error = error || e;
else throw e;
});
- case 153:
+ case 155:
if (!error) {
- _ctx.next = 156;
+ _ctx.next = 158;
break;
}
Router.events.emit(
@@ -5649,7 +5697,7 @@
routeProps
);
throw error;
- case 156:
+ case 158:
if (false) {
}
Router.events.emit(
@@ -5658,8 +5706,8 @@
routeProps
);
return _ctx.abrupt("return", true);
- case 161:
- _ctx.prev = 161;
+ case 163:
+ _ctx.prev = 163;
_ctx.t4 = _ctx["catch"](113);
if (
!(
@@ -5667,13 +5715,13 @@
_ctx.t4.cancelled
)
) {
- _ctx.next = 165;
+ _ctx.next = 167;
break;
}
return _ctx.abrupt("return", false);
- case 165:
+ case 167:
throw _ctx.t4;
- case 166:
+ case 168:
case "end":
return _ctx.stop();
}
@@ -5682,8 +5730,8 @@
null,
[
[39, 51],
- [113, 161],
- [132, 138]
+ [113, 163],
+ [134, 140]
]
);
})
Diff for index.html
@@ -19,7 +19,7 @@
defer=""
></script>
<script
- src="/_next/static/chunks/main-eb6922b25512ec18.js"
+ src="/_next/static/chunks/main-ee04e351dce28253.js"
defer=""
></script>
<script
Diff for link.html
@@ -19,7 +19,7 @@
defer=""
></script>
<script
- src="/_next/static/chunks/main-eb6922b25512ec18.js"
+ src="/_next/static/chunks/main-ee04e351dce28253.js"
defer=""
></script>
<script
Diff for withRouter.html
@@ -19,7 +19,7 @@
defer=""
></script>
<script
- src="/_next/static/chunks/main-eb6922b25512ec18.js"
+ src="/_next/static/chunks/main-ee04e351dce28253.js"
defer=""
></script>
<script
Default Build with SWC (Increase detected ⚠️ )
General Overall increase ⚠️
vercel/next.js canary | janicklas-ralph/next.js script-update | Change | |
---|---|---|---|
buildDuration | 20.9s | 21.5s | |
buildDurationCached | 7.2s | 7.2s | ✓ |
nodeModulesSize | 484 MB | 484 MB |
Page Load Tests Overall decrease ⚠️
vercel/next.js canary | janicklas-ralph/next.js script-update | Change | |
---|---|---|---|
/ failed reqs | 0 | 0 | ✓ |
/ total time (seconds) | 3.764 | 3.751 | -0.01 |
/ avg req/sec | 664.22 | 666.43 | +2.21 |
/error-in-render failed reqs | 0 | 0 | ✓ |
/error-in-render total time (seconds) | 1.501 | 1.605 | |
/error-in-render avg req/sec | 1666.02 | 1557.87 |
Client Bundles (main, webpack) Overall increase ⚠️
vercel/next.js canary | janicklas-ralph/next.js script-update | Change | |
---|---|---|---|
925.HASH.js gzip | 178 B | 178 B | ✓ |
framework-HASH.js gzip | 42.3 kB | 42.3 kB | ✓ |
main-HASH.js gzip | 28.3 kB | 28.5 kB | |
webpack-HASH.js gzip | 1.45 kB | 1.45 kB | ✓ |
Overall change | 72.3 kB | 72.4 kB |
Legacy Client Bundles (polyfills)
vercel/next.js canary | janicklas-ralph/next.js script-update | Change | |
---|---|---|---|
polyfills-HASH.js gzip | 31 kB | 31 kB | ✓ |
Overall change | 31 kB | 31 kB | ✓ |
Client Pages
vercel/next.js canary | janicklas-ralph/next.js script-update | Change | |
---|---|---|---|
_app-HASH.js gzip | 1.35 kB | 1.35 kB | ✓ |
_error-HASH.js gzip | 179 B | 179 B | ✓ |
amp-HASH.js gzip | 313 B | 313 B | ✓ |
css-HASH.js gzip | 325 B | 325 B | ✓ |
dynamic-HASH.js gzip | 3.03 kB | 3.03 kB | ✓ |
head-HASH.js gzip | 351 B | 351 B | ✓ |
hooks-HASH.js gzip | 921 B | 921 B | ✓ |
image-HASH.js gzip | 5.74 kB | 5.74 kB | ✓ |
index-HASH.js gzip | 261 B | 261 B | ✓ |
link-HASH.js gzip | 2.38 kB | 2.38 kB | ✓ |
routerDirect..HASH.js gzip | 322 B | 322 B | ✓ |
script-HASH.js gzip | 388 B | 388 B | ✓ |
withRouter-HASH.js gzip | 317 B | 317 B | ✓ |
85e02e95b279..7e3.css gzip | 107 B | 107 B | ✓ |
Overall change | 16 kB | 16 kB | ✓ |
Client Build Manifests
vercel/next.js canary | janicklas-ralph/next.js script-update | Change | |
---|---|---|---|
_buildManifest.js gzip | 459 B | 459 B | ✓ |
Overall change | 459 B | 459 B | ✓ |
Rendered Page Sizes
vercel/next.js canary | janicklas-ralph/next.js script-update | Change | |
---|---|---|---|
index.html gzip | 532 B | 532 B | ✓ |
link.html gzip | 545 B | 545 B | ✓ |
withRouter.html gzip | 527 B | 527 B | ✓ |
Overall change | 1.6 kB | 1.6 kB | ✓ |
Diffs
Diff for main-HASH.js
@@ -790,9 +790,8 @@
if (false) {
}
if (initialData.scriptLoader) {
- initScriptLoader = __webpack_require__(
- 3573
- ) /* .initScriptLoader */.z;
+ initScriptLoader = __webpack_require__(3573)
+ .initScriptLoader;
initScriptLoader(initialData.scriptLoader);
}
pageLoader = new _pageLoader.default(
@@ -2826,7 +2825,6 @@
__webpack_require__
) {
"use strict";
- var __webpack_unused_export__;
function _arrayLikeToArray(arr, len) {
if (len == null || len > arr.length) len = arr.length;
@@ -2836,6 +2834,16 @@
function _arrayWithHoles(arr) {
if (Array.isArray(arr)) return arr;
}
+ function _arrayWithoutHoles(arr) {
+ if (Array.isArray(arr)) return _arrayLikeToArray(arr);
+ }
+ function _iterableToArray(iter) {
+ if (
+ (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null) ||
+ iter["@@iterator"] != null
+ )
+ return Array.from(iter);
+ }
function _iterableToArrayLimit(arr, i) {
var _i =
arr == null
@@ -2869,6 +2877,11 @@
"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."
);
}
+ function _nonIterableSpread() {
+ throw new TypeError(
+ "Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."
+ );
+ }
function _slicedToArray(arr, i) {
return (
_arrayWithHoles(arr) ||
@@ -2877,6 +2890,14 @@
_nonIterableRest()
);
}
+ function _toConsumableArray(arr) {
+ return (
+ _arrayWithoutHoles(arr) ||
+ _iterableToArray(arr) ||
+ _unsupportedIterableToArray(arr) ||
+ _nonIterableSpread()
+ );
+ }
function _unsupportedIterableToArray(o, minLen) {
if (!o) return;
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
@@ -2889,10 +2910,11 @@
)
return _arrayLikeToArray(o, minLen);
}
- __webpack_unused_export__ = {
+ Object.defineProperty(exports, "__esModule", {
value: true
- };
- exports.z = initScriptLoader;
+ });
+ exports.handleClientScriptLoad = handleClientScriptLoad;
+ exports.initScriptLoader = initScriptLoader;
exports["default"] = void 0;
var _react = _interopRequireWildcard(__webpack_require__(7294));
var _headManagerContext = __webpack_require__(4664);
@@ -3090,14 +3112,14 @@
function handleClientScriptLoad(props) {
var _strategy = props.strategy,
strategy = _strategy === void 0 ? "afterInteractive" : _strategy;
- if (strategy === "afterInteractive") {
- loadScript(props);
- } else if (strategy === "lazyOnload") {
+ if (strategy === "lazyOnload") {
window.addEventListener("load", function() {
(0, _requestIdleCallback).requestIdleCallback(function() {
return loadScript(props);
});
});
+ } else {
+ loadScript(props);
}
}
function loadLazyScript(props) {
@@ -3113,8 +3135,22 @@
});
}
}
+ function addBeforeInteractiveToCache() {
+ var scripts = _toConsumableArray(
+ document.querySelectorAll('[data-nscript="beforeInteractive"]')
+ ).concat(
+ _toConsumableArray(
+ document.querySelectorAll('[data-nscript="beforePageRender"]')
+ )
+ );
+ scripts.forEach(function(script) {
+ var cacheKey = script.id || script.getAttribute("src");
+ LoadCache.add(cacheKey);
+ });
+ }
function initScriptLoader(scriptLoaderItems) {
scriptLoaderItems.forEach(handleClientScriptLoad);
+ addBeforeInteractiveToCache();
}
function Script(props) {
var _src = props.src,
@@ -4342,6 +4378,7 @@
exports["default"] = void 0;
var _normalizeTrailingSlash = __webpack_require__(2700);
var _routeLoader = __webpack_require__(2497);
+ var _script = __webpack_require__(3573);
var _isError = _interopRequireWildcard(__webpack_require__(676));
var _denormalizePagePath = __webpack_require__(4522);
var _normalizeLocalePath = __webpack_require__(4769);
@@ -5011,6 +5048,8 @@
props,
__N_SSG,
__N_SSP,
+ component,
+ scripts,
destination,
parsedHref,
ref3,
@@ -5504,14 +5543,23 @@
(props = routeInfo.props),
(__N_SSG = routeInfo.__N_SSG),
(__N_SSP = routeInfo.__N_SSP);
+ component = routeInfo.Component;
+ if (component && component.scriptLoader) {
+ scripts = [].concat(component.scriptLoader());
+ scripts.forEach(function(script) {
+ (0, _script).handleClientScriptLoad(
+ script.props
+ );
+ });
+ }
if (!((__N_SSG || __N_SSP) && props)) {
- _ctx.next = 144;
+ _ctx.next = 146;
break;
}
if (
!(props.pageProps && props.pageProps.__N_REDIRECT)
) {
- _ctx.next = 129;
+ _ctx.next = 131;
break;
}
destination = props.pageProps.__N_REDIRECT;
@@ -5521,7 +5569,7 @@
props.pageProps.__N_REDIRECT_BASE_PATH !== false
)
) {
- _ctx.next = 127;
+ _ctx.next = 129;
break;
}
parsedHref = (0,
@@ -5541,31 +5589,31 @@
"return",
_this.change(method, newUrl, newAs, options)
);
- case 127:
+ case 129:
window.location.href = destination;
return _ctx.abrupt(
"return",
new Promise(function() {})
);
- case 129:
+ case 131:
nextState.isPreview = !!props.__N_PREVIEW;
if (!(props.notFound === SSG_DATA_NOT_FOUND)) {
- _ctx.next = 144;
+ _ctx.next = 146;
break;
}
- _ctx.prev = 132;
- _ctx.next = 135;
+ _ctx.prev = 134;
+ _ctx.next = 137;
return _this.fetchComponent("/404");
- case 135:
+ case 137:
notFoundRoute = "/404";
- _ctx.next = 141;
+ _ctx.next = 143;
break;
- case 138:
- _ctx.prev = 138;
- _ctx.t3 = _ctx["catch"](132);
+ case 140:
+ _ctx.prev = 140;
+ _ctx.t3 = _ctx["catch"](134);
notFoundRoute = "/_error";
- case 141:
- _ctx.next = 143;
+ case 143:
+ _ctx.next = 145;
return _this.getRouteInfo(
notFoundRoute,
notFoundRoute,
@@ -5578,9 +5626,9 @@
nextState.locale,
nextState.isPreview
);
- case 143:
+ case 145:
routeInfo = _ctx.sent;
- case 144:
+ case 146:
Router.events.emit(
"beforeHistoryChange",
as,
@@ -5618,7 +5666,7 @@
y: 0
}
: null;
- _ctx.next = 153;
+ _ctx.next = 155;
return _this
.set(
_objectSpread({}, nextState, {
@@ -5637,9 +5685,9 @@
if (e.cancelled) error = error || e;
else throw e;
});
- case 153:
+ case 155:
if (!error) {
- _ctx.next = 156;
+ _ctx.next = 158;
break;
}
Router.events.emit(
@@ -5649,7 +5697,7 @@
routeProps
);
throw error;
- case 156:
+ case 158:
if (false) {
}
Router.events.emit(
@@ -5658,8 +5706,8 @@
routeProps
);
return _ctx.abrupt("return", true);
- case 161:
- _ctx.prev = 161;
+ case 163:
+ _ctx.prev = 163;
_ctx.t4 = _ctx["catch"](113);
if (
!(
@@ -5667,13 +5715,13 @@
_ctx.t4.cancelled
)
) {
- _ctx.next = 165;
+ _ctx.next = 167;
break;
}
return _ctx.abrupt("return", false);
- case 165:
+ case 167:
throw _ctx.t4;
- case 166:
+ case 168:
case "end":
return _ctx.stop();
}
@@ -5682,8 +5730,8 @@
null,
[
[39, 51],
- [113, 161],
- [132, 138]
+ [113, 163],
+ [134, 140]
]
);
})
Diff for index.html
@@ -19,7 +19,7 @@
defer=""
></script>
<script
- src="/_next/static/chunks/main-eb6922b25512ec18.js"
+ src="/_next/static/chunks/main-ee04e351dce28253.js"
defer=""
></script>
<script
Diff for link.html
@@ -19,7 +19,7 @@
defer=""
></script>
<script
- src="/_next/static/chunks/main-eb6922b25512ec18.js"
+ src="/_next/static/chunks/main-ee04e351dce28253.js"
defer=""
></script>
<script
Diff for withRouter.html
@@ -19,7 +19,7 @@
defer=""
></script>
<script
- src="/_next/static/chunks/main-eb6922b25512ec18.js"
+ src="/_next/static/chunks/main-ee04e351dce28253.js"
defer=""
></script>
<script
Stats from current PRDefault Build (Increase detected
|
vercel/next.js canary | janicklas-ralph/next.js script-update | Change | |
---|---|---|---|
buildDuration | 16.7s | 17.1s | |
buildDurationCached | 6.7s | 6.6s | -39ms |
nodeModulesSize | 484 MB | 484 MB |
Page Load Tests Overall decrease ⚠️
vercel/next.js canary | janicklas-ralph/next.js script-update | Change | |
---|---|---|---|
/ failed reqs | 0 | 0 | ✓ |
/ total time (seconds) | 3.536 | 3.633 | |
/ avg req/sec | 706.95 | 688.22 | |
/error-in-render failed reqs | 0 | 0 | ✓ |
/error-in-render total time (seconds) | 1.461 | 1.513 | |
/error-in-render avg req/sec | 1711.5 | 1652.63 |
Client Bundles (main, webpack) Overall increase ⚠️
vercel/next.js canary | janicklas-ralph/next.js script-update | Change | |
---|---|---|---|
925.HASH.js gzip | 179 B | 179 B | ✓ |
framework-HASH.js gzip | 42 kB | 42 kB | ✓ |
main-HASH.js gzip | 28 kB | 28.2 kB | |
webpack-HASH.js gzip | 1.44 kB | 1.44 kB | ✓ |
Overall change | 71.7 kB | 71.9 kB |
Legacy Client Bundles (polyfills)
vercel/next.js canary | janicklas-ralph/next.js script-update | Change | |
---|---|---|---|
polyfills-HASH.js gzip | 31 kB | 31 kB | ✓ |
Overall change | 31 kB | 31 kB | ✓ |
Client Pages
vercel/next.js canary | janicklas-ralph/next.js script-update | Change | |
---|---|---|---|
_app-HASH.js gzip | 1.36 kB | 1.36 kB | ✓ |
_error-HASH.js gzip | 192 B | 192 B | ✓ |
amp-HASH.js gzip | 309 B | 309 B | ✓ |
css-HASH.js gzip | 327 B | 327 B | ✓ |
dynamic-HASH.js gzip | 3.05 kB | 3.05 kB | ✓ |
head-HASH.js gzip | 351 B | 351 B | ✓ |
hooks-HASH.js gzip | 920 B | 920 B | ✓ |
image-HASH.js gzip | 5.68 kB | 5.68 kB | ✓ |
index-HASH.js gzip | 263 B | 263 B | ✓ |
link-HASH.js gzip | 2.32 kB | 2.32 kB | ✓ |
routerDirect..HASH.js gzip | 320 B | 320 B | ✓ |
script-HASH.js gzip | 387 B | 387 B | ✓ |
withRouter-HASH.js gzip | 319 B | 319 B | ✓ |
85e02e95b279..7e3.css gzip | 107 B | 107 B | ✓ |
Overall change | 15.9 kB | 15.9 kB | ✓ |
Client Build Manifests
vercel/next.js canary | janicklas-ralph/next.js script-update | Change | |
---|---|---|---|
_buildManifest.js gzip | 460 B | 460 B | ✓ |
Overall change | 460 B | 460 B | ✓ |
Rendered Page Sizes Overall increase ⚠️
vercel/next.js canary | janicklas-ralph/next.js script-update | Change | |
---|---|---|---|
index.html gzip | 531 B | 532 B | |
link.html gzip | 545 B | 546 B | |
withRouter.html gzip | 525 B | 526 B | |
Overall change | 1.6 kB | 1.6 kB |
Diffs
Diff for main-HASH.js
@@ -790,9 +790,8 @@
if (false) {
}
if (initialData.scriptLoader) {
- initScriptLoader = __webpack_require__(
- 3573
- ) /* .initScriptLoader */.z;
+ initScriptLoader = __webpack_require__(3573)
+ .initScriptLoader;
initScriptLoader(initialData.scriptLoader);
}
pageLoader = new _pageLoader.default(
@@ -2826,7 +2825,6 @@
__webpack_require__
) {
"use strict";
- var __webpack_unused_export__;
function _arrayLikeToArray(arr, len) {
if (len == null || len > arr.length) len = arr.length;
@@ -2836,6 +2834,16 @@
function _arrayWithHoles(arr) {
if (Array.isArray(arr)) return arr;
}
+ function _arrayWithoutHoles(arr) {
+ if (Array.isArray(arr)) return _arrayLikeToArray(arr);
+ }
+ function _iterableToArray(iter) {
+ if (
+ (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null) ||
+ iter["@@iterator"] != null
+ )
+ return Array.from(iter);
+ }
function _iterableToArrayLimit(arr, i) {
var _i =
arr == null
@@ -2869,6 +2877,11 @@
"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."
);
}
+ function _nonIterableSpread() {
+ throw new TypeError(
+ "Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."
+ );
+ }
function _slicedToArray(arr, i) {
return (
_arrayWithHoles(arr) ||
@@ -2877,6 +2890,14 @@
_nonIterableRest()
);
}
+ function _toConsumableArray(arr) {
+ return (
+ _arrayWithoutHoles(arr) ||
+ _iterableToArray(arr) ||
+ _unsupportedIterableToArray(arr) ||
+ _nonIterableSpread()
+ );
+ }
function _unsupportedIterableToArray(o, minLen) {
if (!o) return;
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
@@ -2889,10 +2910,11 @@
)
return _arrayLikeToArray(o, minLen);
}
- __webpack_unused_export__ = {
+ Object.defineProperty(exports, "__esModule", {
value: true
- };
- exports.z = initScriptLoader;
+ });
+ exports.handleClientScriptLoad = handleClientScriptLoad;
+ exports.initScriptLoader = initScriptLoader;
exports["default"] = void 0;
var _react = _interopRequireWildcard(__webpack_require__(7294));
var _headManagerContext = __webpack_require__(4664);
@@ -3090,14 +3112,14 @@
function handleClientScriptLoad(props) {
var _strategy = props.strategy,
strategy = _strategy === void 0 ? "afterInteractive" : _strategy;
- if (strategy === "afterInteractive") {
- loadScript(props);
- } else if (strategy === "lazyOnload") {
+ if (strategy === "lazyOnload") {
window.addEventListener("load", function() {
(0, _requestIdleCallback).requestIdleCallback(function() {
return loadScript(props);
});
});
+ } else {
+ loadScript(props);
}
}
function loadLazyScript(props) {
@@ -3113,8 +3135,22 @@
});
}
}
+ function addBeforeInteractiveToCache() {
+ var scripts = _toConsumableArray(
+ document.querySelectorAll('[data-nscript="beforeInteractive"]')
+ ).concat(
+ _toConsumableArray(
+ document.querySelectorAll('[data-nscript="beforePageRender"]')
+ )
+ );
+ scripts.forEach(function(script) {
+ var cacheKey = script.id || script.getAttribute("src");
+ LoadCache.add(cacheKey);
+ });
+ }
function initScriptLoader(scriptLoaderItems) {
scriptLoaderItems.forEach(handleClientScriptLoad);
+ addBeforeInteractiveToCache();
}
function Script(props) {
var _src = props.src,
@@ -4342,6 +4378,7 @@
exports["default"] = void 0;
var _normalizeTrailingSlash = __webpack_require__(2700);
var _routeLoader = __webpack_require__(2497);
+ var _script = __webpack_require__(3573);
var _isError = _interopRequireWildcard(__webpack_require__(676));
var _denormalizePagePath = __webpack_require__(4522);
var _normalizeLocalePath = __webpack_require__(4769);
@@ -5011,6 +5048,8 @@
props,
__N_SSG,
__N_SSP,
+ component,
+ scripts,
destination,
parsedHref,
ref3,
@@ -5504,14 +5543,23 @@
(props = routeInfo.props),
(__N_SSG = routeInfo.__N_SSG),
(__N_SSP = routeInfo.__N_SSP);
+ component = routeInfo.Component;
+ if (component && component.scriptLoader) {
+ scripts = [].concat(component.scriptLoader());
+ scripts.forEach(function(script) {
+ (0, _script).handleClientScriptLoad(
+ script.props
+ );
+ });
+ }
if (!((__N_SSG || __N_SSP) && props)) {
- _ctx.next = 144;
+ _ctx.next = 146;
break;
}
if (
!(props.pageProps && props.pageProps.__N_REDIRECT)
) {
- _ctx.next = 129;
+ _ctx.next = 131;
break;
}
destination = props.pageProps.__N_REDIRECT;
@@ -5521,7 +5569,7 @@
props.pageProps.__N_REDIRECT_BASE_PATH !== false
)
) {
- _ctx.next = 127;
+ _ctx.next = 129;
break;
}
parsedHref = (0,
@@ -5541,31 +5589,31 @@
"return",
_this.change(method, newUrl, newAs, options)
);
- case 127:
+ case 129:
window.location.href = destination;
return _ctx.abrupt(
"return",
new Promise(function() {})
);
- case 129:
+ case 131:
nextState.isPreview = !!props.__N_PREVIEW;
if (!(props.notFound === SSG_DATA_NOT_FOUND)) {
- _ctx.next = 144;
+ _ctx.next = 146;
break;
}
- _ctx.prev = 132;
- _ctx.next = 135;
+ _ctx.prev = 134;
+ _ctx.next = 137;
return _this.fetchComponent("/404");
- case 135:
+ case 137:
notFoundRoute = "/404";
- _ctx.next = 141;
+ _ctx.next = 143;
break;
- case 138:
- _ctx.prev = 138;
- _ctx.t3 = _ctx["catch"](132);
+ case 140:
+ _ctx.prev = 140;
+ _ctx.t3 = _ctx["catch"](134);
notFoundRoute = "/_error";
- case 141:
- _ctx.next = 143;
+ case 143:
+ _ctx.next = 145;
return _this.getRouteInfo(
notFoundRoute,
notFoundRoute,
@@ -5578,9 +5626,9 @@
nextState.locale,
nextState.isPreview
);
- case 143:
+ case 145:
routeInfo = _ctx.sent;
- case 144:
+ case 146:
Router.events.emit(
"beforeHistoryChange",
as,
@@ -5618,7 +5666,7 @@
y: 0
}
: null;
- _ctx.next = 153;
+ _ctx.next = 155;
return _this
.set(
_objectSpread({}, nextState, {
@@ -5637,9 +5685,9 @@
if (e.cancelled) error = error || e;
else throw e;
});
- case 153:
+ case 155:
if (!error) {
- _ctx.next = 156;
+ _ctx.next = 158;
break;
}
Router.events.emit(
@@ -5649,7 +5697,7 @@
routeProps
);
throw error;
- case 156:
+ case 158:
if (false) {
}
Router.events.emit(
@@ -5658,8 +5706,8 @@
routeProps
);
return _ctx.abrupt("return", true);
- case 161:
- _ctx.prev = 161;
+ case 163:
+ _ctx.prev = 163;
_ctx.t4 = _ctx["catch"](113);
if (
!(
@@ -5667,13 +5715,13 @@
_ctx.t4.cancelled
)
) {
- _ctx.next = 165;
+ _ctx.next = 167;
break;
}
return _ctx.abrupt("return", false);
- case 165:
+ case 167:
throw _ctx.t4;
- case 166:
+ case 168:
case "end":
return _ctx.stop();
}
@@ -5682,8 +5730,8 @@
null,
[
[39, 51],
- [113, 161],
- [132, 138]
+ [113, 163],
+ [134, 140]
]
);
})
Diff for index.html
@@ -19,7 +19,7 @@
defer=""
></script>
<script
- src="/_next/static/chunks/main-eb6922b25512ec18.js"
+ src="/_next/static/chunks/main-ee04e351dce28253.js"
defer=""
></script>
<script
Diff for link.html
@@ -19,7 +19,7 @@
defer=""
></script>
<script
- src="/_next/static/chunks/main-eb6922b25512ec18.js"
+ src="/_next/static/chunks/main-ee04e351dce28253.js"
defer=""
></script>
<script
Diff for withRouter.html
@@ -19,7 +19,7 @@
defer=""
></script>
<script
- src="/_next/static/chunks/main-eb6922b25512ec18.js"
+ src="/_next/static/chunks/main-ee04e351dce28253.js"
defer=""
></script>
<script
Default Build with SWC (Increase detected ⚠️ )
General Overall increase ⚠️
vercel/next.js canary | janicklas-ralph/next.js script-update | Change | |
---|---|---|---|
buildDuration | 20.6s | 21s | |
buildDurationCached | 7s | 6.6s | -425ms |
nodeModulesSize | 484 MB | 484 MB |
Page Load Tests Overall increase ✓
vercel/next.js canary | janicklas-ralph/next.js script-update | Change | |
---|---|---|---|
/ failed reqs | 0 | 0 | ✓ |
/ total time (seconds) | 3.69 | 3.66 | -0.03 |
/ avg req/sec | 677.57 | 683.06 | +5.49 |
/error-in-render failed reqs | 0 | 0 | ✓ |
/error-in-render total time (seconds) | 1.562 | 1.514 | -0.05 |
/error-in-render avg req/sec | 1600.81 | 1651.01 | +50.2 |
Client Bundles (main, webpack) Overall increase ⚠️
vercel/next.js canary | janicklas-ralph/next.js script-update | Change | |
---|---|---|---|
925.HASH.js gzip | 178 B | 178 B | ✓ |
framework-HASH.js gzip | 42.3 kB | 42.3 kB | ✓ |
main-HASH.js gzip | 28.3 kB | 28.5 kB | |
webpack-HASH.js gzip | 1.45 kB | 1.45 kB | ✓ |
Overall change | 72.3 kB | 72.4 kB |
Legacy Client Bundles (polyfills)
vercel/next.js canary | janicklas-ralph/next.js script-update | Change | |
---|---|---|---|
polyfills-HASH.js gzip | 31 kB | 31 kB | ✓ |
Overall change | 31 kB | 31 kB | ✓ |
Client Pages
vercel/next.js canary | janicklas-ralph/next.js script-update | Change | |
---|---|---|---|
_app-HASH.js gzip | 1.35 kB | 1.35 kB | ✓ |
_error-HASH.js gzip | 179 B | 179 B | ✓ |
amp-HASH.js gzip | 313 B | 313 B | ✓ |
css-HASH.js gzip | 325 B | 325 B | ✓ |
dynamic-HASH.js gzip | 3.03 kB | 3.03 kB | ✓ |
head-HASH.js gzip | 351 B | 351 B | ✓ |
hooks-HASH.js gzip | 921 B | 921 B | ✓ |
image-HASH.js gzip | 5.74 kB | 5.74 kB | ✓ |
index-HASH.js gzip | 261 B | 261 B | ✓ |
link-HASH.js gzip | 2.38 kB | 2.38 kB | ✓ |
routerDirect..HASH.js gzip | 322 B | 322 B | ✓ |
script-HASH.js gzip | 388 B | 388 B | ✓ |
withRouter-HASH.js gzip | 317 B | 317 B | ✓ |
85e02e95b279..7e3.css gzip | 107 B | 107 B | ✓ |
Overall change | 16 kB | 16 kB | ✓ |
Client Build Manifests
vercel/next.js canary | janicklas-ralph/next.js script-update | Change | |
---|---|---|---|
_buildManifest.js gzip | 459 B | 459 B | ✓ |
Overall change | 459 B | 459 B | ✓ |
Rendered Page Sizes
vercel/next.js canary | janicklas-ralph/next.js script-update | Change | |
---|---|---|---|
index.html gzip | 532 B | 532 B | ✓ |
link.html gzip | 545 B | 545 B | ✓ |
withRouter.html gzip | 527 B | 527 B | ✓ |
Overall change | 1.6 kB | 1.6 kB | ✓ |
Diffs
Diff for main-HASH.js
@@ -790,9 +790,8 @@
if (false) {
}
if (initialData.scriptLoader) {
- initScriptLoader = __webpack_require__(
- 3573
- ) /* .initScriptLoader */.z;
+ initScriptLoader = __webpack_require__(3573)
+ .initScriptLoader;
initScriptLoader(initialData.scriptLoader);
}
pageLoader = new _pageLoader.default(
@@ -2826,7 +2825,6 @@
__webpack_require__
) {
"use strict";
- var __webpack_unused_export__;
function _arrayLikeToArray(arr, len) {
if (len == null || len > arr.length) len = arr.length;
@@ -2836,6 +2834,16 @@
function _arrayWithHoles(arr) {
if (Array.isArray(arr)) return arr;
}
+ function _arrayWithoutHoles(arr) {
+ if (Array.isArray(arr)) return _arrayLikeToArray(arr);
+ }
+ function _iterableToArray(iter) {
+ if (
+ (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null) ||
+ iter["@@iterator"] != null
+ )
+ return Array.from(iter);
+ }
function _iterableToArrayLimit(arr, i) {
var _i =
arr == null
@@ -2869,6 +2877,11 @@
"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."
);
}
+ function _nonIterableSpread() {
+ throw new TypeError(
+ "Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."
+ );
+ }
function _slicedToArray(arr, i) {
return (
_arrayWithHoles(arr) ||
@@ -2877,6 +2890,14 @@
_nonIterableRest()
);
}
+ function _toConsumableArray(arr) {
+ return (
+ _arrayWithoutHoles(arr) ||
+ _iterableToArray(arr) ||
+ _unsupportedIterableToArray(arr) ||
+ _nonIterableSpread()
+ );
+ }
function _unsupportedIterableToArray(o, minLen) {
if (!o) return;
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
@@ -2889,10 +2910,11 @@
)
return _arrayLikeToArray(o, minLen);
}
- __webpack_unused_export__ = {
+ Object.defineProperty(exports, "__esModule", {
value: true
- };
- exports.z = initScriptLoader;
+ });
+ exports.handleClientScriptLoad = handleClientScriptLoad;
+ exports.initScriptLoader = initScriptLoader;
exports["default"] = void 0;
var _react = _interopRequireWildcard(__webpack_require__(7294));
var _headManagerContext = __webpack_require__(4664);
@@ -3090,14 +3112,14 @@
function handleClientScriptLoad(props) {
var _strategy = props.strategy,
strategy = _strategy === void 0 ? "afterInteractive" : _strategy;
- if (strategy === "afterInteractive") {
- loadScript(props);
- } else if (strategy === "lazyOnload") {
+ if (strategy === "lazyOnload") {
window.addEventListener("load", function() {
(0, _requestIdleCallback).requestIdleCallback(function() {
return loadScript(props);
});
});
+ } else {
+ loadScript(props);
}
}
function loadLazyScript(props) {
@@ -3113,8 +3135,22 @@
});
}
}
+ function addBeforeInteractiveToCache() {
+ var scripts = _toConsumableArray(
+ document.querySelectorAll('[data-nscript="beforeInteractive"]')
+ ).concat(
+ _toConsumableArray(
+ document.querySelectorAll('[data-nscript="beforePageRender"]')
+ )
+ );
+ scripts.forEach(function(script) {
+ var cacheKey = script.id || script.getAttribute("src");
+ LoadCache.add(cacheKey);
+ });
+ }
function initScriptLoader(scriptLoaderItems) {
scriptLoaderItems.forEach(handleClientScriptLoad);
+ addBeforeInteractiveToCache();
}
function Script(props) {
var _src = props.src,
@@ -4342,6 +4378,7 @@
exports["default"] = void 0;
var _normalizeTrailingSlash = __webpack_require__(2700);
var _routeLoader = __webpack_require__(2497);
+ var _script = __webpack_require__(3573);
var _isError = _interopRequireWildcard(__webpack_require__(676));
var _denormalizePagePath = __webpack_require__(4522);
var _normalizeLocalePath = __webpack_require__(4769);
@@ -5011,6 +5048,8 @@
props,
__N_SSG,
__N_SSP,
+ component,
+ scripts,
destination,
parsedHref,
ref3,
@@ -5504,14 +5543,23 @@
(props = routeInfo.props),
(__N_SSG = routeInfo.__N_SSG),
(__N_SSP = routeInfo.__N_SSP);
+ component = routeInfo.Component;
+ if (component && component.scriptLoader) {
+ scripts = [].concat(component.scriptLoader());
+ scripts.forEach(function(script) {
+ (0, _script).handleClientScriptLoad(
+ script.props
+ );
+ });
+ }
if (!((__N_SSG || __N_SSP) && props)) {
- _ctx.next = 144;
+ _ctx.next = 146;
break;
}
if (
!(props.pageProps && props.pageProps.__N_REDIRECT)
) {
- _ctx.next = 129;
+ _ctx.next = 131;
break;
}
destination = props.pageProps.__N_REDIRECT;
@@ -5521,7 +5569,7 @@
props.pageProps.__N_REDIRECT_BASE_PATH !== false
)
) {
- _ctx.next = 127;
+ _ctx.next = 129;
break;
}
parsedHref = (0,
@@ -5541,31 +5589,31 @@
"return",
_this.change(method, newUrl, newAs, options)
);
- case 127:
+ case 129:
window.location.href = destination;
return _ctx.abrupt(
"return",
new Promise(function() {})
);
- case 129:
+ case 131:
nextState.isPreview = !!props.__N_PREVIEW;
if (!(props.notFound === SSG_DATA_NOT_FOUND)) {
- _ctx.next = 144;
+ _ctx.next = 146;
break;
}
- _ctx.prev = 132;
- _ctx.next = 135;
+ _ctx.prev = 134;
+ _ctx.next = 137;
return _this.fetchComponent("/404");
- case 135:
+ case 137:
notFoundRoute = "/404";
- _ctx.next = 141;
+ _ctx.next = 143;
break;
- case 138:
- _ctx.prev = 138;
- _ctx.t3 = _ctx["catch"](132);
+ case 140:
+ _ctx.prev = 140;
+ _ctx.t3 = _ctx["catch"](134);
notFoundRoute = "/_error";
- case 141:
- _ctx.next = 143;
+ case 143:
+ _ctx.next = 145;
return _this.getRouteInfo(
notFoundRoute,
notFoundRoute,
@@ -5578,9 +5626,9 @@
nextState.locale,
nextState.isPreview
);
- case 143:
+ case 145:
routeInfo = _ctx.sent;
- case 144:
+ case 146:
Router.events.emit(
"beforeHistoryChange",
as,
@@ -5618,7 +5666,7 @@
y: 0
}
: null;
- _ctx.next = 153;
+ _ctx.next = 155;
return _this
.set(
_objectSpread({}, nextState, {
@@ -5637,9 +5685,9 @@
if (e.cancelled) error = error || e;
else throw e;
});
- case 153:
+ case 155:
if (!error) {
- _ctx.next = 156;
+ _ctx.next = 158;
break;
}
Router.events.emit(
@@ -5649,7 +5697,7 @@
routeProps
);
throw error;
- case 156:
+ case 158:
if (false) {
}
Router.events.emit(
@@ -5658,8 +5706,8 @@
routeProps
);
return _ctx.abrupt("return", true);
- case 161:
- _ctx.prev = 161;
+ case 163:
+ _ctx.prev = 163;
_ctx.t4 = _ctx["catch"](113);
if (
!(
@@ -5667,13 +5715,13 @@
_ctx.t4.cancelled
)
) {
- _ctx.next = 165;
+ _ctx.next = 167;
break;
}
return _ctx.abrupt("return", false);
- case 165:
+ case 167:
throw _ctx.t4;
- case 166:
+ case 168:
case "end":
return _ctx.stop();
}
@@ -5682,8 +5730,8 @@
null,
[
[39, 51],
- [113, 161],
- [132, 138]
+ [113, 163],
+ [134, 140]
]
);
})
Diff for index.html
@@ -19,7 +19,7 @@
defer=""
></script>
<script
- src="/_next/static/chunks/main-eb6922b25512ec18.js"
+ src="/_next/static/chunks/main-ee04e351dce28253.js"
defer=""
></script>
<script
Diff for link.html
@@ -19,7 +19,7 @@
defer=""
></script>
<script
- src="/_next/static/chunks/main-eb6922b25512ec18.js"
+ src="/_next/static/chunks/main-ee04e351dce28253.js"
defer=""
></script>
<script
Diff for withRouter.html
@@ -19,7 +19,7 @@
defer=""
></script>
<script
- src="/_next/static/chunks/main-eb6922b25512ec18.js"
+ src="/_next/static/chunks/main-ee04e351dce28253.js"
defer=""
></script>
<script
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left a couple comments, looks good from testing other than that and should be good to land as it shouldn't be breaking
Thanks! Made the changes. LMK if theres anything needed else for approval. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to land as no breaking changes are present and new behavior is under unstable_
prefix
Changes to the beforeInteractive strategy to make it work for streaming
Splitting
beforeInteractive
into two strategiesbeforeInteractive
at the _document level andbeforePageRender
for page level