-
Notifications
You must be signed in to change notification settings - Fork 27.5k
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
JS modules are loaded twice #11107
Comments
Can you turn off your experimental usage of the modern behavior and see if this persists? |
The issue seems resolved using the configuration:
|
(I've updated the title, since my assumption of the root cause may be incorrect ;-) ) |
I am having the exact same problem and do not have my experimental config turned on. According to the sourcemap, there are 2 places loading the JS files: // at page-loader.js
.
.
.
function appendLink(href, rel, as) {
return new Promise((res,rej,link)=>{
link = document.createElement('link');
link.crossOrigin = process.crossOrigin;
link.href = href;
link.rel = rel;
if (as)
link.as = as;
link.onload = res;
link.onerror = rej;
document.head.appendChild(link); // <--- Here
}
);
}
.
.
. and at document root (i.e. the HTML served) the actual |
I am not sure if this is related but the reported First Load JS sizes are also roughly twice the size of First Load JS shared by all (which looks suspicious/weird): Page Size First Load JS
┌ λ / 1.73 kB 227 kB
├ /_app 5.92 kB 105 kB
├ ○ /404 769 B 210 kB
├ λ /forgot-password 1.32 kB 227 kB
├ λ /login 1.33 kB 227 kB
├ ○ /offline 1 kB 211 kB
├ λ /reset-password 2.37 kB 228 kB
├ λ /signup 1.31 kB 227 kB
└ λ /todos 3.11 kB 228 kB
+ First Load JS shared by all 105 kB
├ static/pages/_app.js 5.92 kB
├ chunks/3704887d5176932cc40c267af232f229c1b773b4.e8a25d.js 41.7 kB
├ chunks/commons.f7f234.js 10.5 kB
├ chunks/framework.126679.js 40.4 kB
├ runtime/main.89a34b.js 6.02 kB
└ runtime/webpack.c21266.js 794 B
|
And here is my const dotenv = require("dotenv");
const withSourceMaps = require("@zeit/next-source-maps");
const withSitemap = require("next-with-sitemap");
dotenv.config();
module.exports = withSourceMaps()(
withSitemap({
compress: true,
env: {
GQL_URL: process.env.GQL_URL,
GQL_AUTHORIZATION: Buffer.from(
`${process.env.GQL_CLIENT_ID}:${process.env.GQL_CLIENT_SECRET}`
).toString("base64"),
GTM_ID: process.env.GTM_ID,
GTM_AUTH: process.env.GTM_AUTH,
GTM_PREVIEW: process.env.GTM_PREVIEW,
},
pageExtensions: ["page.js"],
sitemap: {
baseUrl: `${
process.env.SECURE_SSL_REDIRECT !== "false" ? "https" : "http"
}://${process.env.WEB_DOMAIN}`,
},
})
); and some of my library versions:
|
I want to speculate this issue might be related with #9070 |
Huh, this is not happening on actual production, only happens when I run: cansin@localhost web % export NODE_ENV=production
cansin@localhost web % yarn next build
cansin@localhost web % yarn next start locally. So perhaps it is a false alarm? If so, I wonder what is the right way to simulate production locally. |
Ok, I changed ports and back and this problem disappeared. Perhaps some kind of stale module hot-reload shenanigan was happening, despite trying to run a prod build. Sorry for the misdirection. |
Closing this issue as the issue no longer reproduces on nextjs.org and these experimental features have been enabled by default for a while (minus modern), with no further reports. |
Hi @Timer , I still can reproduce this issue on a lot of sites, including nextjs.org Could you, please, clarify this behaviour? Is it expected? |
Hi @Timer |
We're seeing the same behavior as well on the latest version of Next.js 10.0.6 |
This seems to be happening in Chrome, or perhaps Chromium based browsers in general (didn't test that) in newer versions of next.js. In Firefox it seems like no request is duplicated. However, older versions of next.js don't seem to suffer from this issue even in Chrome. For reference I'm testing this on Ubuntu 20.04 using Chrome 88.0.4324.182 and Firefox 86.0. Just specifying this in case it isn't reproducible on macOS / Windows, in which case it might be an issue with Chrome on Ubuntu. Below some information with screenshots taken in Chrome. I'm currently running Additionally I did the same thing @andrei-svistunou did and can confirm that nextjs.org has this issue: I've also tried setting the experimental options mentioned at the start of this issue to see if that would resolve it, I tried: {
experimental: {
granularChunks: false,
css: false,
modern: false,
}
} but alas, no luck here either. A friend and colleague of mine also has a next.js website using Let me know if you want me to try anything to see if it resolves the issue and last but certainly not least, thanks for building such an awesome framework, I'm loving every bit of it! EDIT I've downgraded my own website to |
Fix vercel#11107 - don't prefetch preloaded modules
@SidOfc If you want to test it out, the easiest way would be to search for If you need a solution that lasts a little longer you could always point your package.json to my fork of nextjs instead of the official one, but I really don't recommend that long term (or even just in production for that matter) because it will be unmaintained. |
@Sheraff alright, I did a search and found one occurrence in I think the issue lies elsewhere, as I mentioned in my original comment (and can be seen in this screenshot) the requests seem to be coming from the I hope this helps further narrowing it down a bit, if there's anything else you'd like me to try feel free to suggest, I think I can make any change necessary in the EDIT Also noticing that |
@SidOfc some duplication is normal and expected w/ nextjs. Some of it will appear from the To give you an example, from vercel.com, this is what is normal: And this is what we're trying to avoid: In both cases, one of the requests comes from the |
@Sheraff I see, indeed I did have cache disabled while testing this, thanks for pointing this out. After 1 reload I still noticed some requests were duplicated but after a second reload indeed all requests are correctly retrieved from prefetch/disk cache as seen in your screenshots. The only thing I might add would be that this works flawlessly when using I'm adding this just to further clarify why some resources might be loading twice in certain scenarios, Next.js has no control over how these static files get served so this is definitely not a Next.js issue. Thank you for your time, effort, and explanation. It's much appreciated and clears up [my] confusion about how this works. I think I'll be switching back to EDIT P.S. is there any way to buy you a crate of beer or something? |
@SidOfc Yeah I haven't tried setting cache headers w/ Next, my current project uses an express server (because it was started before next@10) and all cache headers are written from there. I'm usually pretty happy w/ magic internet points, but there is always the buy me a coffee thing for special occasions. |
More than happy to reward the kindness and constructiveness, enjoy 👍 |
This PR proposes a fix for #11107 (JS modules are loaded twice). A more detailed explanation of the investigation that led to this PR can be found in the issue's comments (#11107 (comment)). ## Replicability To identify that the issue replicates on any given project, you need to 1. look at the network tab (first/clean load of site, so preferably ⌘+⇧+R on an incognito tab), 2. sort by "name", and filter requests by `mime-type:application/javascript` (selecting "JS" in the devtools filters will actually show all "script" types, but ignore all "javascript" types) 3. look for pairs of identical calls with one originating from initial HTML (`preload` of priority "high" originating from "(index)" or "([page name])") and another one from a script (`prefetch` of priority "lowest" originating from a .js file), where neither of the files is served from the cache. Here's a screenshot of an example of what to look for: <img width="601" alt="Screen Shot 2021-03-07 at 09 59 18" src="https://user-images.githubusercontent.com/1325721/110234627-cf1c6d00-7f2b-11eb-9cd7-749bf881ba56.png"> The issue was reproduced easily on the following projects: - On [nextjs.org](https://nextjs.org/) where duplicates add up to ~70kB of transferred javascript out of 470kB (14.9%). - On [vercel.com](https://vercel.com/) where duplicates add up to ~105kB of transferred javascript out of 557kB (18.8%). - On [tiktok.com](https://tiktok.com/en) where duplicates add up to ~514kB of transferred javascript out of 1556kB (33%). - In my own project using `"next": "^10.0.1"` (private repo) where duplicates add up to about 5% of total transferred javascript. - In the issue's comments, a developer reported a replication using `"^10.0.7"` on a [public repo](https://github.com/SidOfc/sidneyliebrand.io). ## Some information about the fix - Both `preload` and `prefetch` values for `<link rel="x">` behave similarly, with the difference being in network priority level (preload is high priority, prefetch is lowest priority). - Next.js uses `<link rel="preload">` in its initial HTML but then *only* uses `<link rel="prefetch">` for the rest of the lifetime of the page. - However, when Next.js detects that a script should be requested in advance, it only checks for matching `<link rel="prefetch">` and not `<link rel="preload">` (which have higher priority and are present earlier in the DOM, thus have a greater likelihood of being already loaded). This PR aims to fix that oversight. ## Potential issues (none AFAIK) As far as I can tell by looking through the codebase, **there is no downside** not to add a `prefetch` when a `preload` is already in the DOM. No other script looks for a `<link>` based on its `rel` attribute.
This issue has been automatically locked due to no recent activity. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you. |
This PR proposes a fix for vercel#11107 (JS modules are loaded twice). A more detailed explanation of the investigation that led to this PR can be found in the issue's comments (vercel#11107 (comment)). ## Replicability To identify that the issue replicates on any given project, you need to 1. look at the network tab (first/clean load of site, so preferably ⌘+⇧+R on an incognito tab), 2. sort by "name", and filter requests by `mime-type:application/javascript` (selecting "JS" in the devtools filters will actually show all "script" types, but ignore all "javascript" types) 3. look for pairs of identical calls with one originating from initial HTML (`preload` of priority "high" originating from "(index)" or "([page name])") and another one from a script (`prefetch` of priority "lowest" originating from a .js file), where neither of the files is served from the cache. Here's a screenshot of an example of what to look for: <img width="601" alt="Screen Shot 2021-03-07 at 09 59 18" src="https://user-images.githubusercontent.com/1325721/110234627-cf1c6d00-7f2b-11eb-9cd7-749bf881ba56.png"> The issue was reproduced easily on the following projects: - On [nextjs.org](https://nextjs.org/) where duplicates add up to ~70kB of transferred javascript out of 470kB (14.9%). - On [vercel.com](https://vercel.com/) where duplicates add up to ~105kB of transferred javascript out of 557kB (18.8%). - On [tiktok.com](https://tiktok.com/en) where duplicates add up to ~514kB of transferred javascript out of 1556kB (33%). - In my own project using `"next": "^10.0.1"` (private repo) where duplicates add up to about 5% of total transferred javascript. - In the issue's comments, a developer reported a replication using `"^10.0.7"` on a [public repo](https://github.com/SidOfc/sidneyliebrand.io). ## Some information about the fix - Both `preload` and `prefetch` values for `<link rel="x">` behave similarly, with the difference being in network priority level (preload is high priority, prefetch is lowest priority). - Next.js uses `<link rel="preload">` in its initial HTML but then *only* uses `<link rel="prefetch">` for the rest of the lifetime of the page. - However, when Next.js detects that a script should be requested in advance, it only checks for matching `<link rel="prefetch">` and not `<link rel="preload">` (which have higher priority and are present earlier in the DOM, thus have a greater likelihood of being already loaded). This PR aims to fix that oversight. ## Potential issues (none AFAIK) As far as I can tell by looking through the codebase, **there is no downside** not to add a `prefetch` when a `preload` is already in the DOM. No other script looks for a `<link>` based on its `rel` attribute.
Bug report
Describe the bug
JS modules seem to be loaded twice
To Reproduce
Steps to reproduce the behavior:
Expected behavior
All required resources to be loaded just once.
Screenshots
System information
Additional context
When disabling granular loading in next.js config, the issue seems resolved.
The text was updated successfully, but these errors were encountered: