-
Notifications
You must be signed in to change notification settings - Fork 20
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
Incomplete/incorrectly cached pages? #18
Comments
Which caches are you using? For the page cache it's very important that a page renders exactly the same for a given path. I've seen it happen where state in the Nuxt app is set based on request headers or other factors, for example to determine the language. This won't be part of the cache key and will lead to serving a page rendered in language A, but client side code decides language B should be used, leading to hydration mismatch. Also keep in mind that V1 does not properly support running on multiple instances. The cache is done in-memory, so each instance has its own cache. When you invalidate the cache using the API it will only invalidate it in the instance that responds to the API request. You would have to somehow implement a way to execute the API request against each of the 4 node instances. In addition, when using component cache, it's also important that a cached component exclusively gets its data via props (e.g. no Vuex, this.$route, etc.), so that the cache key can be determined given the props. Using external state can lead to such bugs as well. |
Many thanks for the quick response! I currently have the pageCache, the componentCache and the dataCache enabled, but I'm only testing the caching of pages and now also the first components. On the Page I set the caching behavior in the asyncData:
[Note: I have injected $cache to $multicache because another plugin has used $cache] When I query the pages in the cache via the API I get:
Yes, I had this thought earlier as well. I need to talk to a colleague again about this. I've just started with the component cache, and unfortunately I also have the problem here that the contents of the cache are not output correctly. A component is probably not suitable for caching if it contains something like:
I don't understand the error in the output at all. It seems that it still works in the first SSR requests and after a few refeshs no more navigation points are output in the footer. Unfortunately, I don't understand why this behavior is like this. It looks as if the whole component no longer works, also in CSR. |
One thing you could try is to disable JavaScript temporarily in your browser, refresh several times and check if the navigation points are actually contained in the SSR markup and thus disappear due to client side JS.
This would definitely fall in the category of not allowed in a cached component 😄 I think this might also be what causes the issues with the page cache: A first request to Now, this is not an unsolvable problem: The module provides a way for you to manually build the cache key for the page. By default, the cache key in our example would be You can do this by providing a custom nuxt.config.tsfunction getCacheKey(route: string, context: any) {
const req = context.req as Request
const path = req.originalUrl
const isLoggedIn = true // Determine the auth status.
const isMobileDevice = true // Determine the device type.
return [
path,
isLoggedIn ? 'loggedIn' : 'anonymous',
isMobileDevice ? 'mobile' : 'desktop'
].join('--')
}
export default {
multiCache: {
enabled: true,
pageCache: {
enabled: true,
getCacheKey
},
}
} Unfortunately it's not possible to access For the component cache it's pretty similar, but much easier, because you can pass Now, there is also another way to solve the problem. This is also what I do in my projects. Logged in users don't ever get a cached page and also do not put anything into the cache. For that there is the |
Thanks again for your quick reply!
Do you mean that if a page has a component which is based on user data (like in this case) this leads in errors with the page? Could a solution be to set these components to client-only?
That's a good idea, but the component caching was completely not working for me :-(.
Yes, I read about this in the new version docs at https://nuxt-multi-cache.dulnan.net/advanced/enable-cache-conditionally. I will give this a try, but also have the problem with passing $auth at this point, right? |
Yes, I'm pretty confident that this is what's causing the issues. The reason is that during hydration Nuxt expects certain things to be there, based on the state that has been determined when the Nuxt app is initialized client side. This state is now different than the one being used to render the page SSR (likely from a different request). So there is a mismatch between what's in the DOM from SSR and what Nuxt expects.
Yes, that would be a possible solution as well!
I also think that this relates to the global state being used in the component. You could try it with a very simple component, that only renders text, to see if you get that working.
That's true - but in my case I was able to determine the logged in status based on the presence of a certain cookie. If you're using nuxt-auth, this should be pretty straight forward, by default the cookie is prefixed |
Sorry - I have to re-ask for this. I don't see how to do a cookie check in nuxt.config (because the nuxt config is just used in build process i think). But I have to define the enabledForRequest just inside the nuxt.config, right? Sorry but I don't see/understand how to solve this. Maybe you have a litte code example for me? |
In Nuxt 2 the code from nuxt.config.js can be used during runtime of the application, so you can put the methods there. This has changed in Nuxt 3. The docs for V1 are a bit weird, sorry 😄 Here's an example: export default {
multiCache: {
enabled: true,
enabledForRequest: function(req) {
if (req.headers.cookie) {
return req.headers.cookie.includes('auth.')
}
return true
},
pageCache: {
enabled: true,
},
}
} |
Sorry that I have to ask you something again - but I'm stuck here with problems that I don't understand. I have caching enabled for a page and I'm outputting Math.random() after the page title to see if the page comes out of the cache. So I go to the page, press F5 and I keep seeing the same number in the title. So the page should come out of the cache. However, sometimes I don't see any data when I go to http://localhost:3000/__nuxt_multi_cache/stats/page. And even if I call purgeAll, the same number remains on the page, i.e. it should still come from the cache (which, of course, was deleted). But that can't really be?! Even if I stop and restart the local server (npm run dev) I have the same number on the page. That shouldn't be the case either, right? Also the enabledForRequest doesn't seem to work properly. I just had another version in the cache where the main navigation of a logged in user was displayed :-(. I just defined it like this:
|
This is basically impossible. V1 of the module is using lru-cache for caching, which is an in-memory cache that only exists as long as the Nuxt app is running. When you stop Nuxt, the cache is gone. Just out of curiosity: Can you stop the Nuxt server and try to open the page? Is it possible there is another Nuxt process running as well? Also: Do you use the
I just realized the code I suggested had a bug - sorry! This will return // ▼
return !req.headers.cookie.includes('auth._token.local='); |
Thanks again for your feedback and help, and sorry for bothering you with my problems.
Yes, that's what I thought too and I have no explanation for it. I have to discuss this again with my colleagues tomorrow. Currently I could no longer reproduce this behavior after a restart.
No, if I stop the server and go to the site, it's not available. When I look for other processes (ps aux | grep 'nuxt') I don't find any other processes.
No I do not think so. Which setting would that be? We use several other modules, for example the pwa-module or workbox-caching like this:
But I think rhis should not affect the ssr?
Thanks for pointing that out. I have corrected it. Unfortunately the same problems remain. And I also don't get this: With API-Call stats/page I can find my one cached page. If I do purge/all and then stats/page, I can't find anything anymore. However, it still gives me the same random number on the page so I think the page still comes from cache. Do you have any explanation for this? Besides that, it somehow seems that the SSR caching of a page doesn't work properly when I press F5 on the first request. It works in such a way that the complete page is not cached? Or can it be that JS errors mean that the page cannot be properly cached? Unfortunately I'm at a loss... |
Hello! I have a quick additional question: If I understand it correctly, the enabledForRequest controls whether a page from the cache should be displayed for a logged-in user or not. How can I ensure that a page is not cached for logged-in users, i.e. it cannot happen that a page call by a logged-in user caches a page? Do I have to do something like this in the page:
Or does that not make any sense? |
Hello,
I'm currently testing the plugin in the V1 version, there will still be a Nuxt2 application.
I often have the problem that individual pages are not cached correctly. It appears that certain elements are simply missing, e.g. because a background image or buttons are not displayed correctly. Also the dropdown of the main navigation does not work then.
In Sentry I see the following error:
HierarchyRequestError
Object.appendChild(97f3cfd.modern)
Failed to execute 'appendChild' on 'Node': This node type does not support this method.
We have 4 node instances on our server in parallel operation. Here I can see that the page is displayed correctly in some node instances and the error occurs in other instances. I can see this because as a test I appended a Math.random() to the title of the page.
Unfortunately I can't get any further and I don't know how to solve the problem.
I would be grateful for any tips and help!
Best regards
Timo
The text was updated successfully, but these errors were encountered: