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
optimisations for prefetching chunks #14584
Comments
Hello @danielroe . |
@kosmeln Please ensure to use scoped styles ( |
@danielroe As we discussed, we can do both of first items in parallel. Build-time and manifest based page prefetching is probably something we don't want to do in Nuxt 3 since was always tricky in Nuxt 2 when number of pages increases. Only reliable way to predict next pages is runtime rendering. Both Server-Side and Client-Side of |
Thanks for the quick response @pi0. I do aware of this solution and this is what I currently use as a workaround for my project.
Speaking of other use cases, there is an example posted by @engvie of using similar approach when splitting between site and admin pages - see this thread. The workaround that we use (same as you shared) resolves the issue, but the problem is - page pre-fetches all layouts (for my case a dozen of them) and they will never be needed in per-site approach - so this is just the waste of resources. I really hope that there is going to be any mechanisms developed to handle this use-case either in the scope of this ticket or further on. Until then - any other suggestions that you might have are very welcomed. |
Thanks for explaining your use case @kosmeln. Prefetching is not causing any issue but simply reveals a side-effect issue of not using scoped styles in layouts. Using style prefixes is not a workaround but a proper way to write global styles that ensure they don't conflict. I would be more than happy to continue this conversation to investigate different solutions we might provide for this. If you would, please open a discussion and elaborate more about site builder use-case that ends up with dozens of layouts. BTW in Nuxt 3, we have a much better solution for theming and shared code for multi sites depending on same code base but slight changes. It is called extends. |
Thank you @pi0 ! |
I believe this to be related: #16231 As you can see in that discussion, simply removing prefetch tags from my app increases its Lighthouse score by 20%. And I can tell you the app feels and loads faster as well in use. If developers could gain access to |
Maybe it makes sense to include different prefetch strategies for NuxtLink? prefetch in viewport and on NuxtLink hover? |
Despite a manual workaround in which I disable prefetch/preload by modifying vue-bundle-renderer's runtime.mjs, Nuxt seems to be building an unnecessary critical request chain which also damages my Lighthouse scores. I see there are chained requests for numerous pages and resources that are not even in view (I've tried no-prefetch and lazy component loading with no help.) Most of these are "modulepreloads" I don't want, and I can't remove them manually because they seem to be generated at runtime. I want the option not to prefetch, preload, or modulepreload anything at all. It would be great to be able to:
|
@sh0ber If vue-bundle-renderer isn't injecting the prefetches, then it will be Vite that is doing so. If you can provide a reproduction we can identify the cause and either work around it within Nuxt or resolve within Vite. |
I'd just like to question the assumption that disabling prefetching will make sites seem slower. If you have a site with a small number of user flows where the resources will end up getting fetched anyway, then that's true. If you have a site with a large number of user flows where any given user will only do a few of them, then the prefetching will be pulling down a lot of assets that are never used. Even though prefetching happens in the background, that will still chew up CPU on the device, possibly network data for mobile. It can also become significant with data egress allowances/charges for the server side. I think having a very clear "bundle and prefetch everything" or "prefetch nothing and fetch individually as you go" option might be a higher priority than finely granular control. I have this in my nuxt.config.ts:
...but I still see assets fetched which I wouldn't expect on v3.3.2. Is that the correct way of trying to turn off prefetching? Apologies if I've missed something - I've been wandering around in related issues. Is there any way to debug what causes a specific component to get pulled in? |
Hey, @danielroe are you guys planning to finish and release this in any of the upcoming Nuxt versions? |
We are indeed 😊 |
Really need an option to disable I've tried
None of them work even though it seems like it's a part of Vite since version 3.1 As a matter of fact it's not even listed in |
@modbender would you explain a bit more about what, specifically, you want to achieve, in a new issue? 🙏 |
As much as I would love to, I do not have time to create reproduction, and my repository is private for commercial purposes. All I know is, I created 2 sites, both static, deployed on Netlify. One uses only MD files with nuxt/content, while the other uses Strapi with nuxt/content's Now getting to homepage performance on PageSpeed, I get different performance values for both https://nuxt-nova-md.netlify.app/ The problem here is FCP, paint starts late due to all the preloads, and increase LCP too. There is one composable I created There's just too many things going through And also the same large composable gives this in pagespeed: |
@danielroe // app.vue
<LazyAuthBar
v-if='!isPublicNetwork',
:user='user'
/> That is, while on the public network, we still load the
press F for A temporary solution for us for now is to use
...
if (key === 'components/AuthBar.vue') {
file.prefetch = false;
file.preload = false;
}
...
If we don't use UPD More critical is the scenario with the use of a dynamic layout: ...
<NuxtLayout :name="isMobile ? 'mobile' : 'desktop'">
<NuxtPage />
</NuxtLayout>
... Here's the sandbox, try building it and preview it UPD2 As a result, in order not to load components for the desktop version in the mobile version and vice versa, we had to use So I propose to change the default behavior, for |
I'm in the same boat. I really don't want to have to
|
Same for https://pentest-tools.com – screenshots for modulepreload (here too – they're 62 in total). Ideally their number would be around 5-10 max, considering the components used in the homepage specifically. |
While it's really not the fix we wanted, for now we got things slightly improved by:
// nuxt.config.ts
...
hooks: {
// prevent some prefetch behaviour
"build:manifest": (manifest) => {
for (const key in manifest) {
manifest[key].dynamicImports = [];
const file = manifest[key];
if (file.assets) {
file.assets = file.assets.filter(
(assetName) => !/.+\.(gif|jpe?g|png|svg)$/.test(assetName)
);
}
}
}
},
...
vite: {
build: {
rollupOptions: {
output: {
// target ~250KB per chunk in an ideal world
experimentalMinChunkSize: 250 * 1024,
manualChunks: (id, _) => {
// need to avoid touching non-entrypoint files, otherwise it breaks bundling
// because imports aren't idempotent
if (
!id.includes("node_modules") &&
!id.startsWith("virtual:") &&
!id.includes("src") &&
!id.includes("assets")
) {
// merge pages/foo/* as chunk-pg-foo, pages/bar/* as chunk-pg-bar, etc.
// then merge pages/* (ie no subfolder) into chunk-pg-misc
if (id.includes("pages")) {
const parts = id.split("/");
const folderIndex = parts.indexOf("pages");
if (folderIndex + 2 < parts.length) {
const pageGroup = parts[folderIndex + 1];
return `chunk-pg-${pageGroup}`;
}
return "chunk-pg-misc";
}
}
},
},
},
}, While this doesn't solve unnecessary preloading entirely, we went from 200+ chunks (so when accounting for js+css, nearly 500 requests!) to about 30, and avoided hundreds of asset images getting preloaded. I want to stress that outside of wasting time staring at lighthouse scores (they matter, but people do indeed tend to obsess too much about the difference between 90+ and 95+ for example):
It's definitely worth testing a few ways to group pages/components in chunks and running builds to see the outcome. The optimal way varies a lot by website, so don't just copypaste our setup (in our case merging all components together somehow resulted in a much bigger bundle for example, and per-component-folder broke the site, etc. So do test it.) |
How to successfully disable prefetch? |
Are there any plans to configure the config to forcibly disable the prefetch? |
Hi @danielroe it looks like the list in the first post is not up-to-date, all PRs are merged. Could we have a quick summary of the status? Meanwhile, I would like to contribute to solving the issue related to "prefetch" and optimization, could you lead the way or are we stuck somehow? |
Currently dynamic imports include things like routes, error components, and any global components (so if using with
@nuxt/content
). I am very concerned to decrease HTML and number of prefetched resources but if we simply disable prefetching, sites will seem much slower.From my point of view, before removing current prefetch behaviour, we need the ability to make some finer-grained decisions.
A set of suggestions:
prefetch
support via NuxtLink (feat(nuxt): support prefetching<nuxt-link>
framework#4329)<NuxtLink>
prefetch support #13482or smartly add 'sibling' pages: feat(nuxt): exclude page chunks from being prefetched framework#6662(optionally) add a plugin to update manifest so that the components that might use global components are the ones that have the dynamic import registeredadd hook for user to manipulate client manifestvue-bundle-renderer
options - see feat(nuxt): update tovue-bundle-renderer@0.4
framework#6210 (comment).The text was updated successfully, but these errors were encountered: