Skip to content
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

[Docs] CSR / SSR / SSG #589

Closed
vchirikov opened this issue Dec 24, 2022 · 12 comments
Closed

[Docs] CSR / SSR / SSG #589

vchirikov opened this issue Dec 24, 2022 · 12 comments

Comments

@vchirikov
Copy link

Hi, first of all - thanks for your work, awesome.

I have read the documentation and didn't find the information about how to switch between rendering strategies per page for example, is it possible to enable SSG only for certain route parameters and so on.

Could you add this to the docs?

@leoj3n
Copy link
Contributor

leoj3n commented Dec 24, 2022

image

@leoj3n
Copy link
Contributor

leoj3n commented Dec 25, 2022

@leoj3n
Copy link
Contributor

leoj3n commented Dec 25, 2022

I'm trying to understand what people are wanting to do here... If we imagine a website that, for instance, allows users to anonymously edit/publish custom movie poster ideas (plus a blurb for the backstory) and then browse other published submissions... Such a website may have the following parts:

  • Marketing Landing Page (Static page that links to the blog, editing app, and explorer)
  • Paginated List of Blog Posts (List of blog posts with next/prev links and current page number)
  • Blog Page w/ Expandable Comments (Blog post content and comments with expandable replies)
  • Movie Poster Editing App (An app that is heavy along the lines of Figma/Photoshop)
  • Published Movie Posters Explorer (Search functionality and data pulled from an API)

If I understand correctly, people are thinking depending on the vertical route vector the user is hitting, you may want to employ different strategies, perhaps like:

Marketing Landing Page Paginated List of Blog Posts Blog Page w/ Expandable Comments Movie Poster Editing App Published Movie Posters Explorer
SSG SSR SSR CSR Islands?
Default Example Hackernews Demo Hackernews Demo Figma / Photoshop Equivalent Solid Start Movie App
Build-Time (Local Machine) Route-Time (Server) Route-Time (Server) Browser-Time (Client) All-Time? (Server+Client Routing)
CDN-Cache Whole-Hydration Whole-Hydration SPA CDN-Cache Partial-Hydration
Static Streaming Streaming Static Streaming

There are some questions which this raises that may not have clear answers such as:

  • First and foremost, have I understood what people are wanting to do here?
  • Would this add sufficient complexity to make for a bad development tradeoff, or would it be a simple convention?
  • What if the user comes in via one vector (let's say the static marketing page) and then navigates to another vector (let's say any of the other pages)... Will this be a seamless transition, or will this force some suboptimal refresh that is actually a deoptimization on the whole?

Related content:

@vchirikov
Copy link
Author

Let me share my thoughts. I don't think that javascript a good option for backend, for example I prefer C# (aspnetcore), or work with PocketBase api. I DON'T WANT TO USE NODEJS as a backend, and I don't want to use any Edge/Lambda function for rendering. I just want to use nginx/lighttpd/s3 bucket+cloudfront/github pages without any kind of SSR. But nowadays all frameworks provide SSR as first class DX. For example I want to create an app, app might be SPA, it's ok, I don't have requirement to use hydration, it's ok to be an usual app, with dashboard (this page might be prerendered with island hydration for example) and so on, but also I want to have a blog/news pages, where I want to use mdx + i18n, so I think it should be SSG, but all the frameworks are incredible slow or even don't work well with SSG, for example NextJS built-in i18n doesn't work with ssg, If you want to customize mdx generation you should use next-mdx-remote and even then, it doesn't work well. It don't have a cache between builds and you should write something to cache mdx compile results (like contentlayer does), and even then you have incredible slow compilation.

image

14 sec to generate 8 pages with NextJS!

I'm trying to find a framework that does better SSG page generation. If it's really slow due to bundling, let's generate first 10 blog posts and let other routes use CSR (use SSG only for part of page params, like id=1,2,3 SSG, other ids with CSR)...
Of course, I can go with 11ty or hugo to generate blog posts and take a js framework for SPA and hide these 2 different apps with reverse proxy (HAProxy/nginx), but it will be better to have an option use one framework and one app.

@leoj3n
Copy link
Contributor

leoj3n commented Dec 25, 2022

@vchirikov https://astro.build/ has a generator written in Go which is probably the fastest option if you are trying to pre-generate a huge number of routes and it also provides plugins for most JS frameworks hydration scripts that can optionally be deferred until client interaction. It also has an SSR mode, where Astro uses HTML streaming to send each component to the browser as it renders them. While the components you write for Astro look like typical JSX it is actually parsed in Go (via WASM) and just HTML is what's delivered...

@vchirikov
Copy link
Author

@leoj3n thanks, although as far as I know astro is MPA-only framework, so it will refresh a full page for any navigation :( It will be nice to have something like several prerendered entry points (SSG) which after hydration works like SPA (router). And afaik no one has incremental SSG builds (without SSR, at build-time with cache between builds)..
Anyway it will be great to have solid start docs like Svelte

@leoj3n
Copy link
Contributor

leoj3n commented Dec 25, 2022

@vchirikov I think it's not too hard to get SPA router into the MPA... Astro docs:

SPAs can also offer more powerful transitions across page navigation because they control so much about page rendering. To match this support, MPAs leverage tools like Hotwire’s Turbo that mimic client routing by also controlling navigation in the browser. The HTML is still rendered on the server, but Turbo can now display a seamless transition between pages similar to client routing in an SPA.

Note: It sounds like SPA router pro is that it can maintain app state across navigations but a potential con is that may be a deoptimization when it comes to HTML streaming https://youtu.be/ivLhf3hq7eM?t=438
Note2: Astro now has a docs page about sharing state https://docs.astro.build/en/core-concepts/sharing-state/

@leoj3n
Copy link
Contributor

leoj3n commented Dec 25, 2022

@vchirikov You linked the Svelte docs which sounds like they have implemented exactly what you are wanting to do right now... Question for you is why not just use SvelteKit in that case?

As far as I can deduce, currently SolidStart supports many of the same modes but they are not integrated, and instead work on a whole-project basis...

SPA, SSR, Islands, Island Routing or any of SolidStart's other capabilities.

https://start.solidjs.com/api/vite#solid-startvite
The vite plugin exposes the following options:

  • prerenderRoutes (string[], default []): list of route paths to prerender (currently only works with static adapter).
  • ssr (boolean, default true): toggles between client rendering and server rendering (ssr) mode.
  • islands (boolean, default false): experimental toggles on "islands" mode.
  • islandsRouter (boolean, default false): experimental toggles on hybrid "islands" routing.

Note: Looks like Svelte does not yet support partial hydration (sveltejs/kit#1390), but they do have an integrated client router that can support individually pre-rendered pages/routes. So if you want client side routing for animated transitions and such, and can live without partial hydration, Svelte looks like a good choice. So... At the moment, Svelte will allow you to choose the strategy for an entire route, but if that strategy is to hydrate, it is going to hydrate the entire page. If you use Astro, you could have pre-rendered pages that don't hydrate, or pages that have "islands" that get hydrated on user interaction, and so you can have both a strategy for the specific route as well as a kind of basic partial hydration for the page, but unlike Svelte if you want to have client side routing with that you will need to wire that up yourself. If you were to go with SolidStart in the current status, you could have fine partial hydration and the router on the client, but your whole app will have to be this way (every route rendering first on the server instead of just being statically served), unless there is introduced a way to pre-render only certain routes and still have the client router integrated with that. At least this is my understanding as of now.

@ryansolid
Copy link
Member

In setting up for SolidStarts next Beta Phase built on Nitro and Vinxi we are closing all PRs/Issues that will not be merged due to the system changing. If you feel your issue was closed in mistake. Feel free to re-open it after updating/testing against 0.4.x release. Thank you for your patience.

See #1139 for more details.

@leoj3n
Copy link
Contributor

leoj3n commented Mar 14, 2024

@ryansolid Can you give a quick update on where things stand in regards to what was discussed here? Haven't had a chance to keep up with Solid to know if things have changed and am just curious what your thoughts are. If you have a moment to clarify/debunk any assumptions made here, that would be great!

@ryansolid
Copy link
Member

Yeah we are in a much better state now. You can basically make any adapter static by putting:

export default defineConfig({
  server: {
    static: true
    prerender: {
      routes: [] // array of routes
      crawlLinks: true // automatic route detection based on urls
    }
  }
})

This stuff is all documented on Nitro site. And there is some documentation on the start docs: https://start.solidjs.com/core-concepts/route-prerendering

@juji
Copy link

juji commented Jul 27, 2024

Yeah we are in a much better state now. You can basically make any adapter static by putting:

export default defineConfig({
  server: {
    static: true
    prerender: {
      routes: [] // array of routes
      crawlLinks: true // automatic route detection based on urls
    }
  }
})

This stuff is all documented on Nitro site. And there is some documentation on the start docs: https://start.solidjs.com/core-concepts/route-prerendering

The link is now https://docs.solidjs.com/solid-start/building-your-application/route-prerendering

for whoever searching..

thanks @ryansolid

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants