vikejs / vike

🔨 Flexible, lean, community-driven, dependable, fast Vite-based frontend framework.
https://vike.dev
MIT License
4.12k stars 348 forks source link

Partial Hydration #167

Closed ofek-a closed 2 years ago

ofek-a commented 2 years ago

Background & Motivation

Partial hydration is a key differentiator between classical MPAs/Astro and tools like vite-plugin-ssr/Next/Nuxt. Partial hydration is key to achieving high lighthouse scores and improve performance in general.

Most projects that require SSR have prioritized SEO and instant loading of content for their users, whatever the network or device conditions are, instead of doing it all client-side, so it only makes sense that tools that allow SSR also allow partial hydration.

Astro will soon have SSR (it's on their roadmap) and they will compete a lot on mind share.

For more context, read RyanCarniato's tweets, he is talking about it a lot, he is the author of SolidJS and working on the Marko team at eBay: https://twitter.com/RyanCarniato/status/1442715830471389194?s=20

Proposed Solution

I think the islands approach to partial hydration is the future, as in:

This approach has been highly popularized by Astro. Their API is also very straightforward. Here is another attempt to use Vue, Vite with partial hydration, inspired by Astro: https://github.com/ElMassimo/iles

Next steps

I think we should first discuss:

Let me know what you think!

brillout commented 2 years ago

@ElMassimo Would be awesome if we cooperate on that. Would be lovely to have a vite-plugin-ssr + Iles baby somehow.

@OfekA I also see it to be the future. Also React Server Components are super exciting. I think we can discussing this now, and later work on implementing this after we finished the Vike MVP. Thoughts?

brillout commented 2 years ago

@ryansolid

ofek-a commented 2 years ago

@OfekA I also see it to be the future. Also React Server Components are super exciting. I think we can discussing this now, and later work on implementing this after we finished the Vike MVP. Thoughts?

Yeah definitely, I think since we already have SSR streaming this is not as vital right now, but we should definitely start the discussion

brillout commented 2 years ago

👍

ElMassimo commented 2 years ago

Would love to collaborate on this! I'm wrapping up a new release for îles, and have a roadmap that will take a few weeks before I start thinking about supporting SSR, but it's certainly possible with the current architecture.

In particular, packages such as @islands/hydration could be reused.

ryansolid commented 2 years ago

Yeah it's an interesting topic. I consider this a transitional one. Current thinking and approaches are temporary as they don't lend to a universal solution as of yet. Part of this is hydration and lazy loading boundaries are being conflated. Other part is natural mismatch between app structure of SPA vs MPA. You can't hydrate part of a SPA without hydrating its parent. Basically where are today these are conflicting mentalities.

But having tools that provide these manual islands gives a lot of immediate value. I think support for streaming plus partial hydration is where these really come together but it's also the trickiest to coordinate since ideally each island wouldn't be blocking the page and you need to basically handle all the streams coming together.

Biggest consideration is how to present true MPA mode versus SSR+SPA, since for partial hydration to work you need actual MPA. Honestly I think the current tools like Astro are doing a good job of paving the way for MPA but I think that unifying the developer experience so these different architectures are seamless or at least easy to make decisions about is probably the biggest challenge here. Beyond the tools there are different sort of considerations and app architectures that come from it (like MPA tend to have less other JS libraries even when using the common suspects), so much that it needs to be a deliberate decision per page with greater impact than just switching a mode toggle. You write and organize your code differently and that always comes with a mental cost.

brillout commented 2 years ago

I'm busy with higher prio stuff atm, but I'm super interested in this.

Also cc @FredKSchott

Would be so lovely if we could somehow all collaborate on this 😊 @ElMassimo Btw there are some plans for vite-plugin-astro; huge milestone towards deeper collaboration beyond collaborating on Vite's source code.

spacedawwwg commented 2 years ago

This would be very exciting to have a tool that combined these

brillout commented 2 years ago

Yes, and on my side I'd be more than happy to provide an extra API for frameworks.

brillout commented 2 years ago

And just to be clear for those who'd be tempted to re-invent the wheel here: it took me 1 month (full-time) to ship the vite-plugin-ssr MVP (with people using it), but 6 months (full-time hard core) to get it polished for all uses cases. Or see how much effort went into SvelteKit (and it still has a lot of rough edges...)

We're just doing ourselves a favor of collaborating more.

brillout commented 2 years ago

Next.js raised $100M and they agressively started hiring OSS talent such as the lead maintainers of webpack, swc, and NextAuth.js to name a few.

We simply don't stand a chance if we don't collaborate.

@ryansolid @FredKSchott @matthewp @natemoo-re @drwpow @ElMassimo

How much further could we go if we'd collaborate...

Btw. @Aslemammad and myself are implementing telefunc, an RPC implemention similar to Wildcard API but with better DX and marketing. Plan here is that Telefunc can be used by any framework such as Astro, îles, etc.

matthewp commented 2 years ago

Hi @brillout, collaboration could be good, what are you proposing?

ryansolid commented 2 years ago

If I were to try to attack this from a framework-agnostic way. I'd categorize things into 2 piles. Leaf libraries/utilities that are re-usable. Core orchestration pieces that, in theory, should work with any library. The first category I'm sure there are tons of these (like Wildcard or maybes some image utils etc) where it probably isn't too difficult to generalize for consumptions. We are seeing the Vite ecosystem starting to do this a bit anyway. A collection of common utilities (manifests for file based routing anyone) could be valuable for those wishing to put these sort of things together. Maybe the ultimate extension of this something like Svelte's Add-ons. Maybe this already exists in the Vite ecosystem and I'm oblivious but if not it's a direction.

As for the orchestration pieces, that can be a bit more challenging. The backbone of any of these projects is routing and that is where I'd probably start. It is the most critical part for MPA vs SPA, contains the difference between top-down renderers and reactive libraries. In a sense MPA libraries have been able to dodge the bullet here since the routing is basically the server, but if there is any wish to consider hybrid this where it lives. I think there is an interesting question around parallels between nested routing and islands, but to fully leverage it frameworks would probably need to be aware at a template level.

In any sort of breakdown like this communication becomes key. And I wonder if that can stay unopinionated. A perfect example is if you change params on a route that resolves the same component, a Top Down renderer will render the whole thing again and diff any changes.. a reactive library would just update reactive values that cause the places that need to update to do so. Simply calling render on the page/page section is an inadequate approach to being agnostic.

Similarly mechanisms for solving realtime rendering, things like streaming, and interleaving of streams. Almost need to design a universal protocol that every framework would have to adhere to. If the meta container was responsible for data serialization you probably could still make it all work, but that might be at odds with internal methods like Suspense. Could trust each framework to do its own thing but certain combinations of frameworks would probably require some awareness. Anyway just thinking out loud. I'm probably thinking about things Next isn't concerned with at this point, so maybe it's out of scope of this conversation anyway. Next has the advantage of only being focused on React.

In any case interested in the sort of things you are thinking about.

brillout commented 2 years ago

Next.js's fundamental problem is that it's not a collaborative project. It's the old school way of having one big company developing everything, whereas Vite is a platform that fosters an ecosystem of passionate developers such as ourselves.

If the Vite ecosystem collaborates, we will outperform Next.js in both features and performance. And many will join us: senior developers profoundly despise lock-ins and Vercel/Next.js is full of lock-ins. Eventually, it's gonna be Next.js VS a lot of passionate devS.

It was always clear to me that vite-plugin-ssr will and cannot be the end game; there needs to be a wrapper on top of vite-plugin-ssr that offers a zero-config DX, something more like SvelteKit.

I always designed vite-plugin-ssr so that a framework can be built on top of it: a vite-plugin-ssr app essentially consitutes of two parts:

This means that Astro / Solid Start / îles can be built on top of vite-plugin-ssr.

This will save us from re-inventing a ton of subtle things, two recent examples: routing precendence and CSP support. The really neat (and powerful) thing here is that we can polish all these things and everyone benefits.

Thoughts?

Btw. Vike is going to be a full-stack (Frontend + Backend + Database + Deploy) boilerplate generator (little prototype: create-vike). Would be lovely to include Solid Start / Astro / îles to the boilerplates generated by Vike.

Also CC'ing @patak-js @aleclarson @antfu @yyx990803 since this is very much about the Vite ecosystem at large. In the end, it's going to be Vite VS Next.js.

brillout commented 2 years ago

If I were to try to attack this from a framework-agnostic way. I'd categorize things into 2 piles. Leaf libraries/utilities that are re-usable. Core orchestration pieces that, in theory, should work with any library. The first category I'm sure there are tons of these (like Wildcard or maybes some image utils etc) where it probably isn't too difficult to generalize for consumptions.

Agreed.

some image utils

Yes, that will eventually be super important to outperform Next.js.

We are seeing the Vite ecosystem starting to do this a bit anyway.

Yep, and that's actually one thing people like a lot about Vite.

A collection of common utilities (manifests for file based routing anyone) could be valuable for those wishing to put these sort of things together. Maybe the ultimate extension of this something like Svelte's Add-ons. Maybe this already exists in the Vite ecosystem and I'm oblivious but if not it's a direction.

Not sure if this is the best level of abstraction for collaboration. I'd say collaborating on a higher-level would be easier & most helpful (e.g. vite-plugin-ssr).

That said, vite-plugin-import-build can be helpful for other tools to support deploying to the edge (Cloudflare Workers + Vercel).

As for the orchestration pieces, that can be a bit more challenging. The backbone of any of these projects is routing and that is where I'd probably start. It is the most critical part for MPA vs SPA, contains the difference between top-down renderers and reactive libraries. In a sense MPA libraries have been able to dodge the bullet here since the routing is basically the server, but if there is any wish to consider hybrid this where it lives. I think there is an interesting question around parallels between nested routing and islands, but to fully leverage it frameworks would probably need to be aware at a template level.

In any sort of breakdown like this communication becomes key. And I wonder if that can stay unopinionated. A perfect example is if you change params on a route that resolves the same component, a Top Down renderer will render the whole thing again and diff any changes.. a reactive library would just update reactive values that cause the places that need to update to do so. Simply calling render on the page/page section is an inadequate approach to being agnostic.

Agreed. E.g. I expect vite-plugin-ssr's client-side router to need framework awareness. But that's ok as the rest of vite-plugin-ssr stays framework agnostic.

Similarly mechanisms for solving realtime rendering, things like streaming, and interleaving of streams. Almost need to design a universal protocol that every framework would have to adhere to. If the meta container was responsible for data serialization you probably could still make it all work, but that might be at odds with internal methods like Suspense. Could trust each framework to do its own thing but certain combinations of frameworks would probably require some awareness. Anyway just thinking out loud. I'm probably thinking about things Next isn't concerned with at this point, so maybe it's out of scope of this conversation anyway. Next has the advantage of only being focused on React.

Yea I'm not sure we need this, at least not for now AFAICT.

spacedawwwg commented 2 years ago

Would love to collaborate on this! I'm wrapping up a new release for îles, and have a roadmap that will take a few weeks before I start thinking about supporting SSR, but it's certainly possible with the current architecture.

In particular, packages such as @islands/hydration could be reused.

@ElMassimo how much effort do you think it would take to extract the hydration part of Iles into its own package?

mmm8955405 commented 2 years ago

From August last year to August this year! Are there any results?

mmm8955405 commented 2 years ago

I am very disappointed with the official svelte / sveltekit team! They don't deal with any problems. All issues related to Vue \ react will be closed. Or is partial hydration really difficult? Will it take more than a year for there to be no breakthrough? https://github.com/sveltejs/svelte/issues/7757

fgnass commented 2 years ago

Regarding the partial hydration stuff you can also take some inspiration from https://capri.build as it is based on Vite, too. It would be great if the next version of Capri could be built on top of vite-plugin-ssr!

brillout commented 2 years ago

Capri could be built on top of vite-plugin-ssr!

That'd be nice indeed.

Also check out Astro, which is built on top of Vite as well.

I'm closing this ticket because it's more of a user land thing. Partial Hydration should, in principle, already be possible today when using vps.