Skip to content
This repository has been archived by the owner on Apr 6, 2023. It is now read-only.

feat(nuxt): support server components with extracted payloads #10113

Merged
merged 8 commits into from
Jan 20, 2023

Conversation

danielroe
Copy link
Member

@danielroe danielroe commented Jan 16, 2023

πŸ”— Linked issue

❓ Type of change

  • πŸ“– Documentation (updates to the documentation or readme)
  • 🐞 Bug fix (a non-breaking change that fixes an issue)
  • πŸ‘Œ Enhancement (improving an existing functionality like performance)
  • ✨ New feature (a non-breaking change that adds functionality)
  • ⚠️ Breaking change (fix or feature that would cause existing functionality to change)

πŸ“š Description

This builds on #9972 to support server components in fully static websites. It does two things:

  1. it emits standalone data for a server component, e.g. ~/.output/public/__nuxt_island/PureComponent:6LYrSuODRS. This means that server components aren't necessarily tied to the page in which they are used.
  2. it also embeds any server components within a page's payload. This means that when loading a page, the payload can be prefetched without needing to make further network calls when switching to the page.

There is scope for improving this, for example, it's not necessarily to include the HTML in the payload if we could prefetch it. But I don't think this PR binds us to that - it's just an implementation detail at the moment and I would suggest we switch to fully extracted server components once we have a way of prefetching them - maybe through something like #7805.

πŸ“ Checklist

  • I have linked an issue or discussion.
  • I have updated the documentation accordingly.

@danielroe danielroe added enhancement New feature or request 🍰 p2-nice-to-have Priority 2: nothing is broken but it's worth addressing labels Jan 16, 2023
@danielroe danielroe requested a review from pi0 January 16, 2023 00:15
@danielroe danielroe self-assigned this Jan 16, 2023
@codesandbox
Copy link

codesandbox bot commented Jan 16, 2023

CodeSandbox logoCodeSandbox logoΒ  Open in CodeSandbox Web Editor | VS Code | VS Code Insiders

@pi0
Copy link
Member

pi0 commented Jan 16, 2023

This is a good idea to use asyncData to enable payload extraction but on the other hand, we would be unable to implement and support hybrid islands (with remote sources) in static websites.

As far as I know, we currently use dynamic import() and with unique URLs for each island props, the browser/ESM resolver is supposed to cache them for second navigation or rendering. Isn't it happening as expected? (they are supposed to be extracted but in their own chunk basically)

@danielroe
Copy link
Member Author

Nice thought! Created an issue so we can track: nuxt/nuxt#12343. I'll push a fix to this PR so we support both payload extraction and runtime fetching when props are changed.

@pi0
Copy link
Member

pi0 commented Jan 16, 2023

Thanks for creating tracker however i'm still wondering what is the issue we are trying to solve. Island responses are extracted but not in the same payload file and network requests should be cached. Putting their response into one payload, would duplicate them across pages while currently we download a unique island+props in one request.

@danielroe
Copy link
Member Author

danielroe commented Jan 16, 2023

The issue is the waterfall - they aren't fetched until the page starts being loaded, at which point the delay the transition, whereas if they are in the payload then they can be prefetched ahead of time and the page transition is instant.

Moreover, I don't believe they are extracted into separate files at all when generating at the moment - happy to look into it πŸ€”

@pi0
Copy link
Member

pi0 commented Jan 16, 2023

This is by design for islands, in general, to be individually loaded assets (like images). However, they are expected to be pre-rendered if not it is probably a bug.

I guess we can have a separate implementation nuxt-server-island component for the specific purpose of server components then that is inlined into page payloads and optimized without the need to support remotely. Reusing code and server logic as much as possible but optimizing for their purpose.

@danielroe
Copy link
Member Author

Pushed a couple of improvements (and fixed the bug of not emitting island output during prerender) and updated the issue description. Let me know what you think 😊

@pi0
Copy link
Member

pi0 commented Jan 17, 2023

Thanks for the updates. However still, in full static mode with payload extraction, when two pages use the same islands/props, duplicate data would be downloaded (and prefetched) in the payload of each page. Copy islands.vue to islands2.vue in the fixture for example.

Is it possible that we enable useAsyncData behavior only for server-only .server components to leveraging full-static? While keeping <NuxtIsland> to network fetch and rely on browser as is and cache with individual chunks we can experiment with hybrid remote islands easier also . (Since useAsyncData is always cached in the payload.)

@danielroe danielroe added the 3.x label Jan 19, 2023
@danielroe danielroe merged commit 5e1881c into main Jan 20, 2023
@danielroe danielroe deleted the feat/static-server-components branch January 20, 2023 12:11
@danielroe danielroe mentioned this pull request Jan 20, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
3.x enhancement New feature or request 🍰 p2-nice-to-have Priority 2: nothing is broken but it's worth addressing
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants