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
Nuxt does not clean up CSS after navigation (and injects CSS pre-navigation) #22817
Comments
Start a new pull request in StackBlitz Codeflow. |
@danielroe If there's a temporary workaround for this bug, I'd love to know! Thanks! |
@danielroe Or anyone? Any advice on how to work around this? |
apologies for the delay in looking at this. |
@danielroe It's alright, we're all busy people. What I did in the short term was, because I was using Less / SCSS, I wrapped the entirety of styles with a class (which, of course, isn't ideal, since it will expand the length of every selector), and then set the HTML class per template. It works, but yeah I'd love to just have CSS styles work for templates. |
I'm seeing this issue when not using layouts -- simply two different pages. When I |
@galaxyblur Oh okay, so it's safer to say that Nuxt 3 doesn't have proper CSS support yet? |
@matthew-dean No, absolutely not! 😋
IMO This is expected and you can use The same applies to the issue mentioned above I'd say. Fixed example using Happy for some other opinions here though (cc @danielroe) |
I agree with @manniL's take. You should not rely on whether a stylesheet is or isn't loaded. Nuxt may preload a stylesheet when the browser is idle, for example, to ensure that a page loads quickly and doesn't rely on additional network requests. Vite may also bundle multiple pages' or layouts' CSS into a single file if they are very small. These are implementation details. Instead you should use scoped CSS, CSS modules, or unique selectors to ensure there are no conflicts. This is a matter of (IMO) best practice anyway. |
I respectfully disagree, in that yes, it's understandable to preload assets, but
Can we not enable an option to not pre-mount CSS? I tried creating a custom Nuxt Link, but there was no way to use I understand the need to say no for edge cases, so I'm not saying you need to add this as a feature, but could you at least enable a way for me to do it? I feel like even those avenues are blocked. |
The behaviour here is not Nuxt's but Vite's; I would create a proposal or feature request there, that we can then benefit from in Nuxt. |
While this is true for styles applied to individual pages, you cannot scope styles inside a layout, as this will not apply them to the pages using the layout.. so the only real workaround is to encapsulate the layout styles in another parent selector this issue drove me insane when i was trying to reduce css bundle size by splitting them into different layouts. The second you use NuxtLink without disabling prefetching, the styles will get combined again and can cause unexpected behaviour. It also didn't help that this issue was closed, since it makes it more effort to find. In general, I'm distressed that almost all of the major JavaScript SSR frameworks out there happen to have so many gotcha's when handling css. It's very hard to keep control and regularly lures me back to traditional SSR, where you have full control of the HTML for each page. |
You can use the |
Is there a link to this question? I wonder if it's already here |
Note: I discovered today that this is also a problem for just page-to-page CSS, not just layout CSS. Navigating to a new page does not un-mount the CSS for a previous page. Therefore, if a page alters any CSS globals for that page, while the page is mounted, then those globals will persist long after the page is gone. I'm not sure why Nuxt would want the memory leak / performance issue of just endlessly stacking CSS while you navigate around. If you never refresh your page and navigate through 1,000 pages, won't you end up with 1,000 style tags trailing behind you? 🤔
Style tags are not benign if "un-used". The browser still has to build a style tree, and more styles means that takes longer, and it still has to traverse the DOM to know what tags have styles applied, which includes tags in the head. The DOM can (and will) degrade in performance the more elements are added. Leaving style trash in the wake of navigation just doesn't make a lot of sense. |
I wrote a simple test with a Nuxt plugin, which looks like this: import { defineNuxtPlugin } from '#app'
export default defineNuxtPlugin({
name: 'css-register',
hooks: {
'page:loading:start'() {
const styles = document.querySelectorAll('style')
console.log('Number of styles:', styles.length)
}
}
}) I loaded a
I navigated to a
I navigated back to
I navigated back to
Back to
Back to
🙃 |
Reopened to investigate. |
@danielroe I think something like this would be useful when using view-transitions. When you need to animate something with different aspect ratios you should apply different For example, when you go from a wider image to a smaller image
vice versa
|
Environment
Darwin
v16.19.0
3.6.5
2.5.2
pnpm@8.3.1
vite
extends
,srcDir
,build
,hooks
,runtimeConfig
-
-
Reproduction
https://stackblitz.com/edit/nuxt-starter-l1dvnf?file=app.vue
Describe the bug
There's actually two manifestations of this bug.
First bug:
Second bug:
NuxtLink
(<NuxtLink>
withoutnoPrefetch
), then the CSS for template Y will be injected into the page when navigating to page A, even though it has no association with Template Y.Note that the first bug occurs whether or not you use
noPrefetch
.Additional context
I originally thought this bug was associated with / the same bug as #3877, but was told that was not the case, so filing this new issue. I also thought it might be the exact same as this issue, but that issue is closed?
Logs
No response
The text was updated successfully, but these errors were encountered: