Open samtay opened 1 week ago
There are a few different ways to use use_resource
:
1) The default use_resource
without suspense will only run on the client in fullstack/ssg. This version will act like what you described
2) use_resource
with suspense will run on the server and client in ssg, but fail to hydrate because the data isn't serialized between the server and client
3) use_server_future
is a version of use_resource
that serializes the result from the server to the client to fix hydration issues
There are situations where you want a future to only suspend on the client during SSG which currently requires you to config out the suspense on the server. We should probably add a method/hook that supports that usecase.
I could see situations where it is useful to do async work during suspense even during the SSG render. For example, my personal site fetches data for each card asynchronously from Github. You may want to combine client side data that is fresh with server side data that is baked at build time in the same application, so I don't think this should be a setting in the ssg config
You may want to combine client side data that is fresh with server side data that is baked at build time in the same application, so I don't think this should be a setting in the ssg config
Yeah, totally get that some resources make sense to fetch at build time. Global config probably doesn't make sense. I suppose the good news for me is that it is indeed possible to do what I want, I just checked and after removing the suspense (replacing with a simple match resource.value() { None => rsx! { PlaceholderComponent {} }, ... }
), SSG does work for me! Yay!
However, it seems like leaky implementation details that options (1), (2), (3) have such varying behaviors. Perhaps they should all be made to work consistently, and then as you mentioned, add a new method that can configure whether or not to suspend based on the dx platform? Something like
// perhaps keep the default behavior to render all resources
let static_but_remote_resource = use_resource(fetch_content_that_is_largely_static);
// and mark ones that should only be run dynamically
let some_dynamic_feed_resource = use_resource(fetch_dynamic_content).hydrate_only();
but with better names?
SolidJS does something interesting here. They now expose a ssrLoadFrom
option that sets the initial value for ssr and hydration and then reruns the future on the client.
I agree, the options make more sense as methods because you can stack them. You can choose to .start_on_client()
and .suspend()
with the same future. Ideally, the easiest option should be the option we recommend by default. Currently, most of the docs point towards use_resource
to run futures, but that causes poor performance on the server. use_server_future
adds an additional serialization requirement, so it isn't enabled by default.
Instead it might be better to require serialization by default and add a method to skip serialization:
// Acts like `use_server_future` does today with serialization requirement
use_resource().suspend()?;
// Acts like `use_resource` does today without serialization requirement
use_resource().run_on_client().suspend()?;
Feature Request
Currently static site generation is only useful for truly static sites. Like a blog without comments.
This is because the static content that gets rendered will run
use_resource
s to completion. So if you wanted to use SSG for a blog with comments, the initial page load would just contain whatever comments were present at the time the site was generated. Similarly if you had a feed or any dynamic content that might change from time to time, that content would just be stale from the time you generated the site.Implement Suggestion
I think that there should be an option (perhaps in
ssg::Config
?) to render static routes with all resources in the state ofUseResourceState::Pending
, and then have the client side run the resources to completion on page load. This way, your blog would render immediately with potentially nice skeleton placeholders in the comment section, and then they'd hydrate with the actual resources client side.This functionality would basically just let
ssg
be a better version ofweb
-- all of its existing functionality, plus the fast render and SEO benefits fromssg
/fullstack
.I'm interested in working on this if it is feasible as a first Dioxus issue.