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

Question/Feature suggestion: Server side rendering #232

Open
AlterionX opened this issue Oct 4, 2019 · 13 comments
Open

Question/Feature suggestion: Server side rendering #232

AlterionX opened this issue Oct 4, 2019 · 13 comments
Labels
enhancement New feature or request

Comments

@AlterionX
Copy link
Contributor

Is server side rendering being considered at all?

It seems borderline impossible in my head without severe restrictions, but I was just wondering.

@MartinKavik
Copy link
Member

MartinKavik commented Oct 4, 2019

Why do you need it?

I use Seed as a static site generator as an alternative. See seed-quickstart-webpack for an example.

@AlterionX
Copy link
Contributor Author

I've got a login system that dynamically changes the nav menu. I think I want this to happen on the server, since if someone navigates to my site, they'll see the nav menu flash.

To do this, I think I need some form of SSR? Then I got carried away thinking about everything else that could use it.

Also, the rest of my static pages uses maud for rendering, so then I'd need to combine those two systems.

Totally missed the quickstart thing, btw, so thanks.

@MartinKavik
Copy link
Member

MartinKavik commented Oct 5, 2019

nav menu flash

I want to fix one type of flashes - see issue #223.

But you probably think the flash of content once you loaded info about user and want to show e.g. his name and avatar in the menu. I think there are at least two options:

  1. If the site is NOT prerendered, you can load required data in init function (ideally from localStorage - we want it to be synchronous and fast). E.g. seed-rs-realworld uses localStorage that way.

  2. If the site IS prerendered, you can load required data also in init function, but you don't want to block first render. So you can show some placeholders or spinner instead of dynamic page parts.

Also, the rest of my static pages uses maud for rendering, so then I'd need to combine those two systems.

Try to render maud templates into String in init and then render the result in view function with macro raw!í..). Prerender your app and you get HTML static files.

@AlterionX
Copy link
Contributor Author

Well, the real problem I had was how to hook up event listeners, because the wasm is still traveling over the wire and not initialized yet.

The thing about prerendering is that I don't want to write out the templates twice, once with listeners for Seed, and once without for maud. Ideally, I would create another macro or something similar that somehow wraps Seed's things so that I can use maud's html macro directly. Well, I'll see, I guess.

Also, I just made a PR to allow for the initial run to do some bootstrapping. Hopefully, this is a step in the right direction for fixing #223.

@dlight
Copy link

dlight commented Apr 30, 2020

@MartinKavik

Why do you need it?

Hi! My use case is to do the first render on the server, and then "rehydrate" the client to work on a prerendered page. This speeds up the first render and may enable the site to be used with scripts disabled (with some effort).

@MartinKavik
Copy link
Member

@dlight Hi. I would like to know more info, if possible:

  • Why you can't use standard prerendering? (User-specific content, many parts with dynamic content..)
  • How fast is your first render now and how fast you want it to be?
  • What's your backend framework / where will be Seed app hosted?
  • "scripts disabled" - do you have some special users/customers with disabled scripting or you mean something like bots / web scrapers?

@flosse
Copy link
Member

flosse commented Apr 30, 2020

@MartinKavik I have a related usecase on the client side.

I want to render a SVG graphic as String so that I can use it as background property.
Currently I have to hardcode/build the SVG string like this:

const SVG_BG: &str = concat!(
    "<svg xmlns='http://www.w3.org/2000/svg' width='10' height='10'>",
    "<rect width='10' height='10' fill='rgba(76,76,76,1)' />",
    "<line x1='0' y1='5' x2='10' y2='5' stroke='rgba(255,255,255,0.25)' stroke-width='0.125' />",
    "<line x1='5' y1='0' x2='5' y2='10' stroke='rgba(255,255,255,0.25)' stroke-width='0.125' />",
    "</svg>"
);

And here it is used:

let my_style = style! {
    St::BackgroundImage => format!(r#"url("data:image/svg+xml;utf8,{}")"#, SVG_BG);
}

It would be cool to do this dynamically like this:

let svg_bg = a_seed_view_fn(parameters).to_html_string();
let my_style = style! {
    St::BackgroundImage => format!(r#"url("data:image/svg+xml;utf8,{}")"#, svg_bg);
}

@MartinKavik
Copy link
Member

@flosse Isn't it more related to #294 or #414?

@flosse
Copy link
Member

flosse commented Apr 30, 2020

@flosse Isn't it more related to #294 or #414?

Absolutely! I'm sorry for messing up the thread!

@MartinKavik
Copy link
Member

@flosse NP, it's somehow related and I'll need this feature too in Seed's core so we can implement some bigger performance optimizations.

@mikezupper
Copy link

@MartinKavik - An e-commerce catalog is the perfect use case... SEO is critical. You would SSR the pages for SEO/perf reasons (static generation or actix-web, rocket, etc). Once that content gets consumed via browser user, the seed wasm module should preload the state based on the already loaded in DOM. Or Maybe something on the server can embed “state init” info that can be easily loaded into wasm module.
My thoughts immediately go to “event sourcing” ideas... replaying the events to reconstruct the end state. Thoughts? Should I clarify in anyway?

@MartinKavik
Copy link
Member

@mikezupper

  • Personally I try to write apps the way where the client app is "smart" and the backend is "dumb". You can notice it on seed-rs.org - Time Tracker example communicates with a graph database directly through GraphQL - there is no custom server at all.
  • From the maintainer's point of view, I assume SSR would introduce a lot of new code and changes. It means more bugs and maybe bigger file size and reduced performance. But I may be wrong - feel free to experiment with the implementation and create a draft PR once it's ready for a discussion / code review.
  • If I would need to have perfect SEO for most pages and server-side rendering, I would probably look for something like Phoenix LiveView.
  • Or I would try prerendering on the fly / on shedule - see e.g. https://advancedweb.dev/prerendering. There are many services, open-source projects and tutorials about it (e.g. https://codelabs.developers.google.com/codelabs/dynamic-rendering)

@pyrossh
Copy link

pyrossh commented Sep 14, 2021

Sauron has implemented prerendering. Maybe you can take a look at that in this example, https://github.com/ivanceras/sauron/tree/master/examples/progressive-rendering

badhrink added a commit to badhrink/seed that referenced this issue Sep 17, 2021
fosskers pushed a commit that referenced this issue Sep 21, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

7 participants
@dlight @flosse @pyrossh @AlterionX @MartinKavik @mikezupper and others