-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
Server Islands not cacheable #12975
Comments
Please update your reproduction, there's no |
I am not talking about a
|
it seems this is being addressed here #12956 can you confirm? |
Closing as duplicate of #12949 |
That is related, for sure. But it looks like it is just about server islands without any props being passed to it. What about a server island that I pass props to? How should I cache those? For that reason, I don't think this is a duplicate... |
The reproduction and issue talk about "no props" - as I was corrected, but now you bring up server islands with props. |
1 similar comment
The reproduction and issue talk about "no props" - as I was corrected, but now you bring up server islands with props. |
I am talking about props in general from the beginning 🤔 The point is: the same server island should be able to use the same props. <!-- these should share a cache -->
<ServerIsland server:defer /> <!-- same props as next line (no props at all) -->
<ServerIsland server:defer /> <!-- same props as previous line (no props at all) -->
<!-- these should share another cache -->
<ServerIsland server:defer something="test" /> <!-- same props as next line -->
<ServerIsland server:defer something="test" /> <!-- same props as previous line --> I am sorry if that wasn't clear enough, I'll update the reproduction. |
I believe Astro doesn't check if props are static or not, or even if their values are shared across islands. It's possible we could actually improve that |
My workaround for this issue is to use this pattern: https://docs.astro.build/en/guides/client-side-scripts/#pass-frontmatter-variables-to-scripts along with Astro sessions that hold any sensitive user data server side so it doesn’t have to get passed directly back to the server as a prop. Can you say a bit more about your use case? Are the props passed into the server rendered component dynamic for some reason? Where does that dynamism come from? If it comes from the server, you should be able to pass the data in the body instead of the props like above (much easier to just interpolate into the component if it doesn’t need to be accessible from the client side js). If it’s coming from the client side (like a “who is logged in” indicator), the server should also know that, or if you’re eg using a react component you can update it on client side render with a useEffect. |
The use case that I designed the “no props = no encryption” for was browser side caching, which can’t be done on the basis of specific parameters afaik. This is part of why I would like any solution to this to not be cdn specific. spitballing here - would it be possible to send the encrypted props as an X-Component-Props header, then only put a hash of the props in the query string? I only use the node and cloudflare adapters but I believe you’d be able to read the custom headers out on the server side in at least those two if not all adapters. My one concern with this approach is that in public caches it enables chosen plaintext “existence” attacks, where I can check the cache response (explicit hit header or timing) to determine whether someone else was looking at a component with a given prop. For instance a stock ticker that takes the stock symbol as a prop, I could check occasionally to see what stocks were being queried. I think caching is great but would want to be careful with what app innards get exposed to the outside world, and if sensitive data is being passed back and forth at all would probably prefer to use an alternate method to accomplish it. |
The case is mostly for caching server islands in something like a CDN in an e-commerce scenario. declare const items: string[] // <- dynamic, not static {items.map(it => <Component server:defer item={it} />)} This would render a dynamic list of items. As people have said, you can denote cache requests by specific query parameters in your CDN provider, and it's clear that currently, caching by {items.map(it => <Component server:defer server:query={it} item={it} />)} would create a Yes, this takes a bite out of the 2048-byte limit, but considering that the point is caching through a CDN, where even responses to Basically, the mental model shift is from a server island holding dynamic information unique to the specific user viewing a page to a server island holding dynamic information unique to itself regardless of user or page. |
Astro Info
If this issue only occurs in one browser, which browser is a problem?
No response
Describe the Bug
Server islands can't be cached effectively. Yes, you can use cache headers and your CDN will cache it.
BUT on
server
mode. Thep
query param of the auto-generated server island URL will change with every request. (Thep
param should be stable usingstatic
output but I think there are use cases for server islands in server mode (e.g. different cache durations)).Here is a screenshot from my personal page showing two requests in the network tab:
Note that the
p
param changes between requests. You can check it out here if you want (note that I configured CloudFront to ignore thep
param for caching).So the CDN would have to ignore the
p
param but that would result in another issue. Thep
param contains the encrypted props that are passed to the server island component. Ignoring thep
param for caching would result in server islands with different props sharing the same cache. That would not work...So currently you can only choose between:
p
)Why does that happen?
p
changes between requests because theiv
that is used for encryption is random (which it probably should be for strong encryption). See here.What's the expected result?
One idea to prevent the issue:
Add another query param that is a hash of the passed props. The same props would result in the same generated hash.
With that, the CDN could ignore
p
and the caching would work as expected because the new query param would be different for different props and thus not sharing the same cache for them anymore.Link to Minimal Reproducible Example
https://stackblitz.com/edit/github-s2hf8p8k-4ntncmcw
Participation
The text was updated successfully, but these errors were encountered: