-
Notifications
You must be signed in to change notification settings - Fork 26.8k
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
Make Router
state immutable
#33925
Merged
Merged
Make Router
state immutable
#33925
Conversation
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
ijjk
added
created-by: Chrome Aurora
PRs by the Google Chrome team: https://web.dev/aurora
type: next
labels
Feb 2, 2022
This comment was marked as outdated.
This comment was marked as outdated.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
devknoll
requested review from
huozhi,
ijjk,
shuding and
timneutkens
as code owners
February 3, 2022 00:21
This comment has been minimized.
This comment has been minimized.
Stats from current PRDefault Build (Increase detected
|
vercel/next.js canary | azukaru/next.js x-refactor-router-state-2 | Change | |
---|---|---|---|
buildDuration | 14.6s | 14.7s | |
buildDurationCached | 5.8s | 5.6s | -261ms |
nodeModulesSize | 359 MB | 359 MB |
Page Load Tests Overall increase ✓
vercel/next.js canary | azukaru/next.js x-refactor-router-state-2 | Change | |
---|---|---|---|
/ failed reqs | 0 | 0 | ✓ |
/ total time (seconds) | 2.996 | 3.056 | |
/ avg req/sec | 834.43 | 818.12 | |
/error-in-render failed reqs | 0 | 0 | ✓ |
/error-in-render total time (seconds) | 1.312 | 1.263 | -0.05 |
/error-in-render avg req/sec | 1905.3 | 1979.21 | +73.91 |
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary | azukaru/next.js x-refactor-router-state-2 | Change | |
---|---|---|---|
450.HASH.js gzip | 179 B | 179 B | ✓ |
framework-HASH.js gzip | 42 kB | 42 kB | ✓ |
main-HASH.js gzip | 27.4 kB | 27.5 kB | |
webpack-HASH.js gzip | 1.44 kB | 1.44 kB | ✓ |
Overall change | 71.1 kB | 71.2 kB |
Legacy Client Bundles (polyfills)
vercel/next.js canary | azukaru/next.js x-refactor-router-state-2 | Change | |
---|---|---|---|
polyfills-HASH.js gzip | 31 kB | 31 kB | ✓ |
Overall change | 31 kB | 31 kB | ✓ |
Client Pages
vercel/next.js canary | azukaru/next.js x-refactor-router-state-2 | Change | |
---|---|---|---|
_app-HASH.js gzip | 1.36 kB | 1.36 kB | ✓ |
_error-HASH.js gzip | 194 B | 194 B | ✓ |
amp-HASH.js gzip | 312 B | 312 B | ✓ |
css-HASH.js gzip | 326 B | 326 B | ✓ |
dynamic-HASH.js gzip | 2.57 kB | 2.57 kB | ✓ |
head-HASH.js gzip | 350 B | 350 B | ✓ |
hooks-HASH.js gzip | 919 B | 919 B | ✓ |
image-HASH.js gzip | 5.01 kB | 5.01 kB | ✓ |
index-HASH.js gzip | 263 B | 263 B | ✓ |
link-HASH.js gzip | 2.26 kB | 2.26 kB | ✓ |
routerDirect..HASH.js gzip | 321 B | 321 B | ✓ |
script-HASH.js gzip | 383 B | 383 B | ✓ |
withRouter-HASH.js gzip | 318 B | 318 B | ✓ |
85e02e95b279..7e3.css gzip | 107 B | 107 B | ✓ |
Overall change | 14.7 kB | 14.7 kB | ✓ |
Client Build Manifests
vercel/next.js canary | azukaru/next.js x-refactor-router-state-2 | Change | |
---|---|---|---|
_buildManifest.js gzip | 458 B | 458 B | ✓ |
Overall change | 458 B | 458 B | ✓ |
Rendered Page Sizes Overall increase ⚠️
vercel/next.js canary | azukaru/next.js x-refactor-router-state-2 | Change | |
---|---|---|---|
index.html gzip | 532 B | 533 B | |
link.html gzip | 544 B | 546 B | |
withRouter.html gzip | 526 B | 527 B | |
Overall change | 1.6 kB | 1.61 kB |
Diffs
Diff for main-HASH.js
@@ -4688,7 +4688,7 @@
);
};
// represents the current component key
- this.route = (0, _normalizeTrailingSlash).removePathTrailingSlash(
+ var route = (0, _normalizeTrailingSlash).removePathTrailingSlash(
pathname2
);
// set up the component cache (by route keys)
@@ -4698,7 +4698,7 @@
// come again to the errored page.
if (pathname2 !== "/_error") {
var ref;
- this.components[this.route] = {
+ this.components[route] = {
Component: Component,
initial: true,
props: initialProps,
@@ -4718,14 +4718,11 @@
// TODO: Should be remove the following major version as it was never documented
this.events = Router.events;
this.pageLoader = pageLoader;
- this.pathname = pathname2;
- this.query = query1;
// if auto prerendered and dynamic route wait to update asPath
// until after mount to prevent hydration mismatch
var autoExportDynamic =
(0, _isDynamic).isDynamicRoute(pathname2) &&
self.__NEXT_DATA__.autoExport;
- this.asPath = autoExportDynamic ? pathname2 : as1;
this.basePath = basePath;
this.sub = subscription;
this.clc = null;
@@ -4733,17 +4730,24 @@
// make sure to ignore extra popState in safari on navigating
// back from external site
this.isSsr = true;
- this.isFallback = isFallback;
+ this.isLocaleDomain = false;
this.isReady = !!(
self.__NEXT_DATA__.gssp ||
self.__NEXT_DATA__.gip ||
(self.__NEXT_DATA__.appGip && !self.__NEXT_DATA__.gsp) ||
(!autoExportDynamic && !self.location.search && !false)
);
- this.isPreview = !!isPreview;
- this.isLocaleDomain = false;
if (false) {
}
+ this.state = {
+ route: route,
+ pathname: pathname2,
+ query: query1,
+ asPath: autoExportDynamic ? pathname2 : as1,
+ isPreview: !!isPreview,
+ locale: false ? 0 : undefined,
+ isFallback: isFallback
+ };
if (true) {
// make sure "as" doesn't start with double slashes or else it can
// throw an error as it's considered invalid
@@ -4835,6 +4839,7 @@
return _asyncToGenerator(
_runtimeJs.default.mark(function _callee() {
var shouldResolveHref,
+ nextState,
prevLocale,
parsedAs,
localePathResult,
@@ -4900,22 +4905,23 @@
options._h ||
options._shouldResolveHref ||
pathNoQueryHash(url) === pathNoQueryHash(as);
+ nextState = _objectSpread({}, _this.state);
// for static pages with query params in the URL we delay
// marking the router ready until after the query is updated
if (options._h) {
_this.isReady = true;
}
- prevLocale = _this.locale;
+ prevLocale = nextState.locale;
if (true) {
- _ctx.next = 18;
+ _ctx.next = 19;
break;
}
- _this.locale =
+ nextState.locale =
options.locale === false
? _this.defaultLocale
- : options.locale || _this.locale;
+ : options.locale || nextState.locale;
if (typeof options.locale === "undefined") {
- options.locale = _this.locale;
+ options.locale = nextState.locale;
}
parsedAs = (0, _parseRelativeUrl).parseRelativeUrl(
hasBasePath(as) ? delBasePath(as) : as
@@ -4926,7 +4932,8 @@
_this.locales
);
if (localePathResult.detectedLocale) {
- _this.locale = localePathResult.detectedLocale;
+ nextState.locale =
+ localePathResult.detectedLocale;
parsedAs.pathname = addBasePath(
parsedAs.pathname
);
@@ -4946,21 +4953,21 @@
detectedDomain = detectDomainLocale(
_this.domainLocales,
undefined,
- _this.locale
+ nextState.locale
);
// we need to wrap this in the env check again since regenerator runtime
// moves this on its own due to the return
if (false) {
}
if (!didNavigate) {
- _ctx.next = 18;
+ _ctx.next = 19;
break;
}
return _ctx.abrupt(
"return",
new Promise(function() {})
);
- case 18:
+ case 19:
if (!options._h) {
_this.isSsr = false;
}
@@ -4991,10 +4998,10 @@
);
cleanedAs = delLocale(
hasBasePath(as) ? delBasePath(as) : as,
- _this.locale
+ nextState.locale
);
_this._inFlightRoute = as;
- localeChange = prevLocale !== _this.locale;
+ localeChange = prevLocale !== nextState.locale;
if (
!(
!options._h &&
@@ -5002,10 +5009,10 @@
!localeChange
)
) {
- _ctx.next = 35;
+ _ctx.next = 36;
break;
}
- _this.asPath = cleanedAs;
+ nextState.asPath = cleanedAs;
Router.events.emit(
"hashChangeStart",
as,
@@ -5023,28 +5030,32 @@
if (scroll) {
_this.scrollToHash(cleanedAs);
}
- _this.notify(_this.components[_this.route], null);
+ _this.set(
+ nextState,
+ _this.components[nextState.route],
+ null
+ );
Router.events.emit(
"hashChangeComplete",
as,
routeProps
);
return _ctx.abrupt("return", true);
- case 35:
+ case 36:
parsed = (0, _parseRelativeUrl).parseRelativeUrl(
url
);
(pathname = parsed.pathname),
(query = parsed.query);
- _ctx.prev = 38;
+ _ctx.prev = 39;
_ctx.t0 = _slicedToArray;
- _ctx.next = 43;
+ _ctx.next = 44;
return Promise.all([
_this.pageLoader.getPageList(),
(0, _routeLoader).getClientBuildManifest(),
_this.pageLoader.getMiddlewareList()
]);
- case 43:
+ case 44:
_ctx.t1 = _ctx.sent;
ref1 = (0, _ctx.t0)(_ctx.t1, 2);
pages = ref1[0];
@@ -5052,16 +5063,16 @@
(rewrites = ref2.__rewrites),
ref2;
ref1;
- _ctx.next = 54;
+ _ctx.next = 55;
break;
- case 50:
- _ctx.prev = 50;
- _ctx.t2 = _ctx["catch"](38);
+ case 51:
+ _ctx.prev = 51;
+ _ctx.t2 = _ctx["catch"](39);
// If we fail to resolve the page list or client-build manifest, we must
// do a server-side transition:
window.location.href = as;
return _ctx.abrupt("return", false);
- case 54:
+ case 55:
// If asked to change the current URL we should reload the current page
// (not location.reload() but reload getInitialProps and other Next.js stuffs)
// We also need to set the method = replaceState always
@@ -5083,16 +5094,18 @@
if (
!(shouldResolveHref && pathname !== "/_error")
) {
- _ctx.next = 69;
+ _ctx.next = 70;
break;
}
options._shouldResolveHref = true;
if (true) {
- _ctx.next = 68;
+ _ctx.next = 69;
break;
}
rewritesResult = (0, _resolveRewrites).default(
- addBasePath(addLocale(cleanedAs, _this.locale)),
+ addBasePath(
+ addLocale(cleanedAs, nextState.locale)
+ ),
pages,
rewrites,
query,
@@ -5102,12 +5115,12 @@
_this.locales
);
if (!rewritesResult.externalDest) {
- _ctx.next = 64;
+ _ctx.next = 65;
break;
}
location.href = as;
return _ctx.abrupt("return", true);
- case 64:
+ case 65:
resolvedAs = rewritesResult.asPath;
if (
rewritesResult.matchedPage &&
@@ -5119,9 +5132,9 @@
parsed.pathname = addBasePath(pathname);
url = (0, _utils).formatWithValidation(parsed);
}
- _ctx.next = 69;
+ _ctx.next = 70;
break;
- case 68: {
+ case 69: {
parsed.pathname = resolveDynamicRoute(
pathname,
pages
@@ -5132,13 +5145,13 @@
url = (0, _utils).formatWithValidation(parsed);
}
}
- case 69:
+ case 70:
if (isLocalURL(as)) {
- _ctx.next = 74;
+ _ctx.next = 75;
break;
}
if (true) {
- _ctx.next = 72;
+ _ctx.next = 73;
break;
}
throw new Error(
@@ -5150,13 +5163,13 @@
) +
"\nSee more info: https://nextjs.org/docs/messages/invalid-relative-url-external-as"
);
- case 72:
+ case 73:
window.location.href = as;
return _ctx.abrupt("return", false);
- case 74:
+ case 75:
resolvedAs = delLocale(
delBasePath(resolvedAs),
- _this.locale
+ nextState.locale
);
if (
!(
@@ -5169,21 +5182,23 @@
)
)
) {
- _ctx.next = 95;
+ _ctx.next = 96;
break;
}
- _ctx.next = 78;
+ _ctx.next = 79;
return _this._preflightRequest({
as: as,
cache: "production" === "production",
pages: pages,
pathname: pathname,
- query: query
+ query: query,
+ locale: nextState.locale,
+ isPreview: nextState.isPreview
});
- case 78:
+ case 79:
effect = _ctx.sent;
if (!(effect.type === "rewrite")) {
- _ctx.next = 83;
+ _ctx.next = 84;
break;
}
{
@@ -5197,11 +5212,11 @@
parsed.pathname = effect.resolvedHref;
url = (0, _utils).formatWithValidation(parsed);
}
- _ctx.next = 95;
+ _ctx.next = 96;
break;
- case 83:
+ case 84:
if (!(effect.type === "redirect" && effect.newAs)) {
- _ctx.next = 87;
+ _ctx.next = 88;
break;
}
return _ctx.abrupt(
@@ -5213,13 +5228,13 @@
options
)
);
- case 87:
+ case 88:
if (
!(
effect.type === "redirect" && effect.destination
)
) {
- _ctx.next = 92;
+ _ctx.next = 93;
break;
}
window.location.href = effect.destination;
@@ -5227,14 +5242,14 @@
"return",
new Promise(function() {})
);
- case 92:
+ case 93:
if (
!(
effect.type === "refresh" &&
as !== window.location.pathname
)
) {
- _ctx.next = 95;
+ _ctx.next = 96;
break;
}
window.location.href = as;
@@ -5242,13 +5257,13 @@
"return",
new Promise(function() {})
);
- case 95:
+ case 96:
route = (0,
_normalizeTrailingSlash).removePathTrailingSlash(
pathname
);
if (!(0, _isDynamic).isDynamicRoute(route)) {
- _ctx.next = 111;
+ _ctx.next = 112;
break;
}
parsedAs1 = (0, _parseRelativeUrl).parseRelativeUrl(
@@ -5269,7 +5284,7 @@
(shouldInterpolate && !interpolatedAs.result)
)
) {
- _ctx.next = 110;
+ _ctx.next = 111;
break;
}
missingParams = Object.keys(
@@ -5278,7 +5293,7 @@
return !query[param];
});
if (!(missingParams.length > 0)) {
- _ctx.next = 108;
+ _ctx.next = 109;
break;
}
if (false) {
@@ -5306,10 +5321,10 @@
: "incompatible-href-as"
)
);
- case 108:
- _ctx.next = 111;
+ case 109:
+ _ctx.next = 112;
break;
- case 110:
+ case 111:
if (shouldInterpolate) {
as = (0, _utils).formatWithValidation(
Object.assign({}, parsedAs1, {
@@ -5324,36 +5339,38 @@
// Merge params into `query`, overwriting any specified in search
Object.assign(query, routeMatch);
}
- case 111:
+ case 112:
Router.events.emit(
"routeChangeStart",
as,
routeProps
);
- _ctx.prev = 112;
- _ctx.next = 116;
+ _ctx.prev = 113;
+ _ctx.next = 117;
return _this.getRouteInfo(
route,
pathname,
query,
as,
resolvedAs,
- routeProps
+ routeProps,
+ nextState.locale,
+ nextState.isPreview
);
- case 116:
+ case 117:
routeInfo = _ctx.sent;
(error = routeInfo.error),
(props = routeInfo.props),
(__N_SSG = routeInfo.__N_SSG),
(__N_SSP = routeInfo.__N_SSP);
if (!((__N_SSG || __N_SSP) && props)) {
- _ctx.next = 143;
+ _ctx.next = 144;
break;
}
if (
!(props.pageProps && props.pageProps.__N_REDIRECT)
) {
- _ctx.next = 128;
+ _ctx.next = 129;
break;
}
destination = props.pageProps.__N_REDIRECT;
@@ -5363,7 +5380,7 @@
props.pageProps.__N_REDIRECT_BASE_PATH !== false
)
) {
- _ctx.next = 126;
+ _ctx.next = 127;
break;
}
parsedHref = (0,
@@ -5383,31 +5400,31 @@
"return",
_this.change(method, newUrl, newAs, options)
);
- case 126:
+ case 127:
window.location.href = destination;
return _ctx.abrupt(
"return",
new Promise(function() {})
);
- case 128:
- _this.isPreview = !!props.__N_PREVIEW;
+ case 129:
+ nextState.isPreview = !!props.__N_PREVIEW;
if (!(props.notFound === SSG_DATA_NOT_FOUND)) {
- _ctx.next = 143;
+ _ctx.next = 144;
break;
}
- _ctx.prev = 131;
- _ctx.next = 134;
+ _ctx.prev = 132;
+ _ctx.next = 135;
return _this.fetchComponent("/404");
- case 134:
+ case 135:
notFoundRoute = "/404";
- _ctx.next = 140;
+ _ctx.next = 141;
break;
- case 137:
- _ctx.prev = 137;
- _ctx.t3 = _ctx["catch"](131);
+ case 138:
+ _ctx.prev = 138;
+ _ctx.t3 = _ctx["catch"](132);
notFoundRoute = "/_error";
- case 140:
- _ctx.next = 142;
+ case 141:
+ _ctx.next = 143;
return _this.getRouteInfo(
notFoundRoute,
notFoundRoute,
@@ -5416,11 +5433,13 @@
resolvedAs,
{
shallow: false
- }
+ },
+ nextState.locale,
+ nextState.isPreview
);
- case 142:
- routeInfo = _ctx.sent;
case 143:
+ routeInfo = _ctx.sent;
+ case 144:
Router.events.emit(
"beforeHistoryChange",
as,
@@ -5446,7 +5465,7 @@
props.pageProps.statusCode = 500;
}
isValidShallowRoute =
- options.shallow && _this.route === route;
+ options.shallow && nextState.route === route;
shouldScroll =
(_scroll1 = options.scroll) !== null &&
_scroll1 !== void 0
@@ -5458,13 +5477,16 @@
y: 0
}
: null;
- _ctx.next = 152;
+ _ctx.next = 153;
return _this
.set(
- route,
- pathname,
- query,
- cleanedAs,
+ _objectSpread({}, nextState, {
+ route: route,
+ pathname: pathname,
+ query: query,
+ asPath: cleanedAs,
+ isFallback: false
+ }),
routeInfo,
forcedScroll !== null && forcedScroll !== void 0
? forcedScroll
@@ -5474,9 +5496,9 @@
if (e.cancelled) error = error || e;
else throw e;
});
- case 152:
+ case 153:
if (!error) {
- _ctx.next = 155;
+ _ctx.next = 156;
break;
}
Router.events.emit(
@@ -5486,7 +5508,7 @@
routeProps
);
throw error;
- case 155:
+ case 156:
if (false) {
}
Router.events.emit(
@@ -5495,22 +5517,22 @@
routeProps
);
return _ctx.abrupt("return", true);
- case 160:
- _ctx.prev = 160;
- _ctx.t4 = _ctx["catch"](112);
+ case 161:
+ _ctx.prev = 161;
+ _ctx.t4 = _ctx["catch"](113);
if (
!(
(0, _isError).default(_ctx.t4) &&
_ctx.t4.cancelled
)
) {
- _ctx.next = 164;
+ _ctx.next = 165;
break;
}
return _ctx.abrupt("return", false);
- case 164:
- throw _ctx.t4;
case 165:
+ throw _ctx.t4;
+ case 166:
case "end":
return _ctx.stop();
}
@@ -5518,9 +5540,9 @@
_callee,
null,
[
- [38, 50],
- [112, 160],
- [131, 137]
+ [39, 51],
+ [113, 161],
+ [132, 138]
]
);
})
@@ -5695,7 +5717,9 @@
query,
as,
resolvedAs,
- routeProps
+ routeProps,
+ locale,
+ isPreview
) {
var _this = this;
return _asyncToGenerator(
@@ -5800,7 +5824,7 @@
asPath: resolvedAs,
ssg: __N_SSG,
rsc: __N_RSC,
- locale: _this.locale
+ locale: locale
});
}
_ctx.next = 21;
@@ -5811,13 +5835,13 @@
_this.isSsr,
false,
__N_SSG ? _this.sdc : _this.sdr,
- !!__N_SSG && !_this.isPreview
+ !!__N_SSG && !isPreview
)
: _this.getInitialProps(Component, {
pathname: pathname,
query: query,
asPath: as,
- locale: _this.locale,
+ locale: locale,
locales: _this.locales,
defaultLocale: _this.defaultLocale
});
@@ -5872,13 +5896,13 @@
},
{
key: "set",
- value: function set(route, pathname, query, as, data, resetScroll) {
- this.isFallback = false;
- this.route = route;
- this.pathname = pathname;
- this.query = query;
- this.asPath = as;
- return this.notify(data, resetScroll);
+ value: function set(state, data, resetScroll) {
+ this.state = state;
+ return this.sub(
+ data,
+ this.components["/_app"].Component,
+ resetScroll
+ );
}
},
{
@@ -6061,7 +6085,9 @@
cache: true,
pages: pages,
pathname: pathname,
- query: query
+ query: query,
+ locale: _this.locale,
+ isPreview: _this.isPreview
});
case 27:
effects = _ctx.sent;
@@ -6234,7 +6260,7 @@
hasBasePath(options.as)
? delBasePath(options.as)
: options.as,
- _this.locale
+ options.locale
);
_ctx.next = 3;
return _this.pageLoader.getMiddlewareList();
@@ -6262,7 +6288,8 @@
_ctx.next = 9;
return _this._getPreflightData({
preflightHref: options.as,
- shouldCache: options.cache
+ shouldCache: options.cache,
+ isPreview: options.isPreview
});
case 9:
preflight = _ctx.sent;
@@ -6375,15 +6402,11 @@
var _this = this;
var preflightHref = params.preflightHref,
_shouldCache = params.shouldCache,
- shouldCache = _shouldCache === void 0 ? false : _shouldCache;
+ shouldCache = _shouldCache === void 0 ? false : _shouldCache,
+ isPreview = params.isPreview;
var ref = new URL(preflightHref, window.location.href),
cacheKey = ref.href;
- if (
- true &&
- !this.isPreview &&
- shouldCache &&
- this.sde[cacheKey]
- ) {
+ if (true && !isPreview && shouldCache && this.sde[cacheKey]) {
return Promise.resolve(this.sde[cacheKey]);
}
return fetch(preflightHref, {
@@ -6448,13 +6471,45 @@
}
},
{
- key: "notify",
- value: function notify(data, resetScroll) {
- return this.sub(
- data,
- this.components["/_app"].Component,
- resetScroll
- );
+ key: "route",
+ get: function get() {
+ return this.state.route;
+ }
+ },
+ {
+ key: "pathname",
+ get: function get() {
+ return this.state.pathname;
+ }
+ },
+ {
+ key: "query",
+ get: function get() {
+ return this.state.query;
+ }
+ },
+ {
+ key: "asPath",
+ get: function get() {
+ return this.state.asPath;
+ }
+ },
+ {
+ key: "locale",
+ get: function get() {
+ return this.state.locale;
+ }
+ },
+ {
+ key: "isFallback",
+ get: function get() {
+ return this.state.isFallback;
+ }
+ },
+ {
+ key: "isPreview",
+ get: function get() {
+ return this.state.isPreview;
}
}
]);
Diff for index.html
@@ -19,7 +19,7 @@
defer=""
></script>
<script
- src="/_next/static/chunks/main-c877b69dffe2b7fd.js"
+ src="/_next/static/chunks/main-3720cf9ee02892d9.js"
defer=""
></script>
<script
Diff for link.html
@@ -19,7 +19,7 @@
defer=""
></script>
<script
- src="/_next/static/chunks/main-c877b69dffe2b7fd.js"
+ src="/_next/static/chunks/main-3720cf9ee02892d9.js"
defer=""
></script>
<script
Diff for withRouter.html
@@ -19,7 +19,7 @@
defer=""
></script>
<script
- src="/_next/static/chunks/main-c877b69dffe2b7fd.js"
+ src="/_next/static/chunks/main-3720cf9ee02892d9.js"
defer=""
></script>
<script
Default Build with SWC (Increase detected ⚠️ )
General Overall increase ⚠️
vercel/next.js canary | azukaru/next.js x-refactor-router-state-2 | Change | |
---|---|---|---|
buildDuration | 17.6s | 17.8s | |
buildDurationCached | 5.5s | 5.8s | |
nodeModulesSize | 359 MB | 359 MB |
Page Load Tests Overall increase ✓
vercel/next.js canary | azukaru/next.js x-refactor-router-state-2 | Change | |
---|---|---|---|
/ failed reqs | 0 | 0 | ✓ |
/ total time (seconds) | 3.004 | 2.955 | -0.05 |
/ avg req/sec | 832.22 | 846.01 | +13.79 |
/error-in-render failed reqs | 0 | 0 | ✓ |
/error-in-render total time (seconds) | 1.301 | 1.257 | -0.04 |
/error-in-render avg req/sec | 1921.6 | 1988.73 | +67.13 |
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary | azukaru/next.js x-refactor-router-state-2 | Change | |
---|---|---|---|
450.HASH.js gzip | 179 B | 179 B | ✓ |
framework-HASH.js gzip | 42.1 kB | 42.1 kB | ✓ |
main-HASH.js gzip | 27.4 kB | 27.6 kB | |
webpack-HASH.js gzip | 1.44 kB | 1.44 kB | ✓ |
Overall change | 71.2 kB | 71.3 kB |
Legacy Client Bundles (polyfills)
vercel/next.js canary | azukaru/next.js x-refactor-router-state-2 | Change | |
---|---|---|---|
polyfills-HASH.js gzip | 31 kB | 31 kB | ✓ |
Overall change | 31 kB | 31 kB | ✓ |
Client Pages
vercel/next.js canary | azukaru/next.js x-refactor-router-state-2 | Change | |
---|---|---|---|
_app-HASH.js gzip | 1.35 kB | 1.35 kB | ✓ |
_error-HASH.js gzip | 180 B | 180 B | ✓ |
amp-HASH.js gzip | 305 B | 305 B | ✓ |
css-HASH.js gzip | 321 B | 321 B | ✓ |
dynamic-HASH.js gzip | 2.56 kB | 2.56 kB | ✓ |
head-HASH.js gzip | 342 B | 342 B | ✓ |
hooks-HASH.js gzip | 911 B | 911 B | ✓ |
image-HASH.js gzip | 5.05 kB | 5.05 kB | ✓ |
index-HASH.js gzip | 256 B | 256 B | ✓ |
link-HASH.js gzip | 2.28 kB | 2.28 kB | ✓ |
routerDirect..HASH.js gzip | 314 B | 314 B | ✓ |
script-HASH.js gzip | 375 B | 375 B | ✓ |
withRouter-HASH.js gzip | 309 B | 309 B | ✓ |
85e02e95b279..7e3.css gzip | 107 B | 107 B | ✓ |
Overall change | 14.7 kB | 14.7 kB | ✓ |
Client Build Manifests
vercel/next.js canary | azukaru/next.js x-refactor-router-state-2 | Change | |
---|---|---|---|
_buildManifest.js gzip | 460 B | 460 B | ✓ |
Overall change | 460 B | 460 B | ✓ |
Rendered Page Sizes Overall decrease ✓
vercel/next.js canary | azukaru/next.js x-refactor-router-state-2 | Change | |
---|---|---|---|
index.html gzip | 534 B | 533 B | -1 B |
link.html gzip | 548 B | 547 B | -1 B |
withRouter.html gzip | 528 B | 527 B | -1 B |
Overall change | 1.61 kB | 1.61 kB | -3 B |
Diffs
Diff for main-HASH.js
@@ -4688,7 +4688,7 @@
);
};
// represents the current component key
- this.route = (0, _normalizeTrailingSlash).removePathTrailingSlash(
+ var route = (0, _normalizeTrailingSlash).removePathTrailingSlash(
pathname2
);
// set up the component cache (by route keys)
@@ -4698,7 +4698,7 @@
// come again to the errored page.
if (pathname2 !== "/_error") {
var ref;
- this.components[this.route] = {
+ this.components[route] = {
Component: Component,
initial: true,
props: initialProps,
@@ -4718,14 +4718,11 @@
// TODO: Should be remove the following major version as it was never documented
this.events = Router.events;
this.pageLoader = pageLoader;
- this.pathname = pathname2;
- this.query = query1;
// if auto prerendered and dynamic route wait to update asPath
// until after mount to prevent hydration mismatch
var autoExportDynamic =
(0, _isDynamic).isDynamicRoute(pathname2) &&
self.__NEXT_DATA__.autoExport;
- this.asPath = autoExportDynamic ? pathname2 : as1;
this.basePath = basePath;
this.sub = subscription;
this.clc = null;
@@ -4733,17 +4730,24 @@
// make sure to ignore extra popState in safari on navigating
// back from external site
this.isSsr = true;
- this.isFallback = isFallback;
+ this.isLocaleDomain = false;
this.isReady = !!(
self.__NEXT_DATA__.gssp ||
self.__NEXT_DATA__.gip ||
(self.__NEXT_DATA__.appGip && !self.__NEXT_DATA__.gsp) ||
(!autoExportDynamic && !self.location.search && !false)
);
- this.isPreview = !!isPreview;
- this.isLocaleDomain = false;
if (false) {
}
+ this.state = {
+ route: route,
+ pathname: pathname2,
+ query: query1,
+ asPath: autoExportDynamic ? pathname2 : as1,
+ isPreview: !!isPreview,
+ locale: false ? 0 : undefined,
+ isFallback: isFallback
+ };
if (true) {
// make sure "as" doesn't start with double slashes or else it can
// throw an error as it's considered invalid
@@ -4835,6 +4839,7 @@
return _asyncToGenerator(
_runtimeJs.default.mark(function _callee() {
var shouldResolveHref,
+ nextState,
prevLocale,
parsedAs,
localePathResult,
@@ -4900,22 +4905,23 @@
options._h ||
options._shouldResolveHref ||
pathNoQueryHash(url) === pathNoQueryHash(as);
+ nextState = _objectSpread({}, _this.state);
// for static pages with query params in the URL we delay
// marking the router ready until after the query is updated
if (options._h) {
_this.isReady = true;
}
- prevLocale = _this.locale;
+ prevLocale = nextState.locale;
if (true) {
- _ctx.next = 18;
+ _ctx.next = 19;
break;
}
- _this.locale =
+ nextState.locale =
options.locale === false
? _this.defaultLocale
- : options.locale || _this.locale;
+ : options.locale || nextState.locale;
if (typeof options.locale === "undefined") {
- options.locale = _this.locale;
+ options.locale = nextState.locale;
}
parsedAs = (0, _parseRelativeUrl).parseRelativeUrl(
hasBasePath(as) ? delBasePath(as) : as
@@ -4926,7 +4932,8 @@
_this.locales
);
if (localePathResult.detectedLocale) {
- _this.locale = localePathResult.detectedLocale;
+ nextState.locale =
+ localePathResult.detectedLocale;
parsedAs.pathname = addBasePath(
parsedAs.pathname
);
@@ -4946,21 +4953,21 @@
detectedDomain = detectDomainLocale(
_this.domainLocales,
undefined,
- _this.locale
+ nextState.locale
);
// we need to wrap this in the env check again since regenerator runtime
// moves this on its own due to the return
if (false) {
}
if (!didNavigate) {
- _ctx.next = 18;
+ _ctx.next = 19;
break;
}
return _ctx.abrupt(
"return",
new Promise(function() {})
);
- case 18:
+ case 19:
if (!options._h) {
_this.isSsr = false;
}
@@ -4991,10 +4998,10 @@
);
cleanedAs = delLocale(
hasBasePath(as) ? delBasePath(as) : as,
- _this.locale
+ nextState.locale
);
_this._inFlightRoute = as;
- localeChange = prevLocale !== _this.locale;
+ localeChange = prevLocale !== nextState.locale;
if (
!(
!options._h &&
@@ -5002,10 +5009,10 @@
!localeChange
)
) {
- _ctx.next = 35;
+ _ctx.next = 36;
break;
}
- _this.asPath = cleanedAs;
+ nextState.asPath = cleanedAs;
Router.events.emit(
"hashChangeStart",
as,
@@ -5023,28 +5030,32 @@
if (scroll) {
_this.scrollToHash(cleanedAs);
}
- _this.notify(_this.components[_this.route], null);
+ _this.set(
+ nextState,
+ _this.components[nextState.route],
+ null
+ );
Router.events.emit(
"hashChangeComplete",
as,
routeProps
);
return _ctx.abrupt("return", true);
- case 35:
+ case 36:
parsed = (0, _parseRelativeUrl).parseRelativeUrl(
url
);
(pathname = parsed.pathname),
(query = parsed.query);
- _ctx.prev = 38;
+ _ctx.prev = 39;
_ctx.t0 = _slicedToArray;
- _ctx.next = 43;
+ _ctx.next = 44;
return Promise.all([
_this.pageLoader.getPageList(),
(0, _routeLoader).getClientBuildManifest(),
_this.pageLoader.getMiddlewareList()
]);
- case 43:
+ case 44:
_ctx.t1 = _ctx.sent;
ref1 = (0, _ctx.t0)(_ctx.t1, 2);
pages = ref1[0];
@@ -5052,16 +5063,16 @@
(rewrites = ref2.__rewrites),
ref2;
ref1;
- _ctx.next = 54;
+ _ctx.next = 55;
break;
- case 50:
- _ctx.prev = 50;
- _ctx.t2 = _ctx["catch"](38);
+ case 51:
+ _ctx.prev = 51;
+ _ctx.t2 = _ctx["catch"](39);
// If we fail to resolve the page list or client-build manifest, we must
// do a server-side transition:
window.location.href = as;
return _ctx.abrupt("return", false);
- case 54:
+ case 55:
// If asked to change the current URL we should reload the current page
// (not location.reload() but reload getInitialProps and other Next.js stuffs)
// We also need to set the method = replaceState always
@@ -5083,16 +5094,18 @@
if (
!(shouldResolveHref && pathname !== "/_error")
) {
- _ctx.next = 69;
+ _ctx.next = 70;
break;
}
options._shouldResolveHref = true;
if (true) {
- _ctx.next = 68;
+ _ctx.next = 69;
break;
}
rewritesResult = (0, _resolveRewrites).default(
- addBasePath(addLocale(cleanedAs, _this.locale)),
+ addBasePath(
+ addLocale(cleanedAs, nextState.locale)
+ ),
pages,
rewrites,
query,
@@ -5102,12 +5115,12 @@
_this.locales
);
if (!rewritesResult.externalDest) {
- _ctx.next = 64;
+ _ctx.next = 65;
break;
}
location.href = as;
return _ctx.abrupt("return", true);
- case 64:
+ case 65:
resolvedAs = rewritesResult.asPath;
if (
rewritesResult.matchedPage &&
@@ -5119,9 +5132,9 @@
parsed.pathname = addBasePath(pathname);
url = (0, _utils).formatWithValidation(parsed);
}
- _ctx.next = 69;
+ _ctx.next = 70;
break;
- case 68: {
+ case 69: {
parsed.pathname = resolveDynamicRoute(
pathname,
pages
@@ -5132,13 +5145,13 @@
url = (0, _utils).formatWithValidation(parsed);
}
}
- case 69:
+ case 70:
if (isLocalURL(as)) {
- _ctx.next = 74;
+ _ctx.next = 75;
break;
}
if (true) {
- _ctx.next = 72;
+ _ctx.next = 73;
break;
}
throw new Error(
@@ -5150,13 +5163,13 @@
) +
"\nSee more info: https://nextjs.org/docs/messages/invalid-relative-url-external-as"
);
- case 72:
+ case 73:
window.location.href = as;
return _ctx.abrupt("return", false);
- case 74:
+ case 75:
resolvedAs = delLocale(
delBasePath(resolvedAs),
- _this.locale
+ nextState.locale
);
if (
!(
@@ -5169,21 +5182,23 @@
)
)
) {
- _ctx.next = 95;
+ _ctx.next = 96;
break;
}
- _ctx.next = 78;
+ _ctx.next = 79;
return _this._preflightRequest({
as: as,
cache: "production" === "production",
pages: pages,
pathname: pathname,
- query: query
+ query: query,
+ locale: nextState.locale,
+ isPreview: nextState.isPreview
});
- case 78:
+ case 79:
effect = _ctx.sent;
if (!(effect.type === "rewrite")) {
- _ctx.next = 83;
+ _ctx.next = 84;
break;
}
{
@@ -5197,11 +5212,11 @@
parsed.pathname = effect.resolvedHref;
url = (0, _utils).formatWithValidation(parsed);
}
- _ctx.next = 95;
+ _ctx.next = 96;
break;
- case 83:
+ case 84:
if (!(effect.type === "redirect" && effect.newAs)) {
- _ctx.next = 87;
+ _ctx.next = 88;
break;
}
return _ctx.abrupt(
@@ -5213,13 +5228,13 @@
options
)
);
- case 87:
+ case 88:
if (
!(
effect.type === "redirect" && effect.destination
)
) {
- _ctx.next = 92;
+ _ctx.next = 93;
break;
}
window.location.href = effect.destination;
@@ -5227,14 +5242,14 @@
"return",
new Promise(function() {})
);
- case 92:
+ case 93:
if (
!(
effect.type === "refresh" &&
as !== window.location.pathname
)
) {
- _ctx.next = 95;
+ _ctx.next = 96;
break;
}
window.location.href = as;
@@ -5242,13 +5257,13 @@
"return",
new Promise(function() {})
);
- case 95:
+ case 96:
route = (0,
_normalizeTrailingSlash).removePathTrailingSlash(
pathname
);
if (!(0, _isDynamic).isDynamicRoute(route)) {
- _ctx.next = 111;
+ _ctx.next = 112;
break;
}
parsedAs1 = (0, _parseRelativeUrl).parseRelativeUrl(
@@ -5269,7 +5284,7 @@
(shouldInterpolate && !interpolatedAs.result)
)
) {
- _ctx.next = 110;
+ _ctx.next = 111;
break;
}
missingParams = Object.keys(
@@ -5278,7 +5293,7 @@
return !query[param];
});
if (!(missingParams.length > 0)) {
- _ctx.next = 108;
+ _ctx.next = 109;
break;
}
if (false) {
@@ -5306,10 +5321,10 @@
: "incompatible-href-as"
)
);
- case 108:
- _ctx.next = 111;
+ case 109:
+ _ctx.next = 112;
break;
- case 110:
+ case 111:
if (shouldInterpolate) {
as = (0, _utils).formatWithValidation(
Object.assign({}, parsedAs1, {
@@ -5324,36 +5339,38 @@
// Merge params into `query`, overwriting any specified in search
Object.assign(query, routeMatch);
}
- case 111:
+ case 112:
Router.events.emit(
"routeChangeStart",
as,
routeProps
);
- _ctx.prev = 112;
- _ctx.next = 116;
+ _ctx.prev = 113;
+ _ctx.next = 117;
return _this.getRouteInfo(
route,
pathname,
query,
as,
resolvedAs,
- routeProps
+ routeProps,
+ nextState.locale,
+ nextState.isPreview
);
- case 116:
+ case 117:
routeInfo = _ctx.sent;
(error = routeInfo.error),
(props = routeInfo.props),
(__N_SSG = routeInfo.__N_SSG),
(__N_SSP = routeInfo.__N_SSP);
if (!((__N_SSG || __N_SSP) && props)) {
- _ctx.next = 143;
+ _ctx.next = 144;
break;
}
if (
!(props.pageProps && props.pageProps.__N_REDIRECT)
) {
- _ctx.next = 128;
+ _ctx.next = 129;
break;
}
destination = props.pageProps.__N_REDIRECT;
@@ -5363,7 +5380,7 @@
props.pageProps.__N_REDIRECT_BASE_PATH !== false
)
) {
- _ctx.next = 126;
+ _ctx.next = 127;
break;
}
parsedHref = (0,
@@ -5383,31 +5400,31 @@
"return",
_this.change(method, newUrl, newAs, options)
);
- case 126:
+ case 127:
window.location.href = destination;
return _ctx.abrupt(
"return",
new Promise(function() {})
);
- case 128:
- _this.isPreview = !!props.__N_PREVIEW;
+ case 129:
+ nextState.isPreview = !!props.__N_PREVIEW;
if (!(props.notFound === SSG_DATA_NOT_FOUND)) {
- _ctx.next = 143;
+ _ctx.next = 144;
break;
}
- _ctx.prev = 131;
- _ctx.next = 134;
+ _ctx.prev = 132;
+ _ctx.next = 135;
return _this.fetchComponent("/404");
- case 134:
+ case 135:
notFoundRoute = "/404";
- _ctx.ne
Post job cleanup.
[command]/usr/bin/git version
git version 2.35.1
[command]/usr/bin/git config --local --name-only --get-regexp core\.sshCommand
[command]/usr/bin/git submodule foreach --recursive git config --local --name-only --get-regexp 'core\.sshCommand' && git config --local --unset-all 'core.sshCommand' || :
[command]/usr/bin/git config --local --name-only --get-regexp http\.https\:\/\/github\.com\/\.extraheader
http.https://github.com/.extraheader
[command]/usr/bin/git config --local --unset-all http.https://github.com/.extraheader
[command]/usr/bin/git submodule foreach --recursive git config --local --name-only --get-regexp 'http\.https\:\/\/github\.com\/\.extraheader' && git config --local --unset-all 'http.https://github.com/.extraheader' || :
Cleaning up orphan processes
Commit: 8fd9f8c753222bdf8889bdd0191696696991bd8b
huozhi
approved these changes
Feb 7, 2022
shuding
approved these changes
Feb 7, 2022
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, it would be great if we can add a test case for it.
ijjk
approved these changes
Feb 7, 2022
natew
pushed a commit
to natew/next.js
that referenced
this pull request
Feb 16, 2022
Make the external `Router` state immutable, and make it so there's only one place (`set`) where it is changed and announced. This is to prepare for vercel#33919, which ensures that we only create a new router once per tree.
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Labels
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Make the external
Router
state immutable, and make it so there's only one place (set
) where it is changed and announced. This is to prepare for #33919, which ensures that we only create a new router once per tree.