How best to use Resources in a Fastboot context
roomman opened this issue · comments
Hi @NullVoxPopuli, you very kindly described how I could await a Resource. I'm hoping I can pick your brains a little more?
I'm building a site that will have multiple "audiences". I have a service that tracks audience
. I'm using a headless CMS that allows me to include audience
in my request, and returns the relevant version of the page content. I have a page component that includes a FetchContent
Resource, which requests content whenever audience
changes.
Using a Resource has been a fab experience so far - thanks!
The issue I am having now is with Fastboot. Because Resources are non-blocking, Fastboot is returning a rendered version of the page before the Resource has completed the fetch. As such, I have lots of empty elements in the document. As soon as Ember takes over from Fastboot, the Resource makes the request and the content appears. It's almost imperceptible on a standard network connection but with some throttling, you see it happen, and it's having a negative impact on Lighthouse scores.
Is there a pattern that would allow me to use a Resource in one way for Fastboot (an async/await approach) but in a non-blocking way once Fastboot gets out of the way?
I know I'm asking to have my cake and eat it, and it may even be that a Resource isn't the right fit in this scenario. Do you have thoughts?
Using a Resource has been a fab experience so far - thanks!
🎉 ❤️
Is there a pattern that would allow me to use a Resource in one way for Fastboot (an async/await approach) but in a non-blocking way once Fastboot gets out of the way?
Not really -- it kinda sounds like you want the behavior of routes? -- routes are for the minimally required data to render a page, and may be what you want?
other than that though, there is a possibility of using loading skeletons to at least reduce layout shifting as the resources kick-in once the browsers loads all your code.
one option I saw from @josemarluedke's glimmer-apollo is to expose a promise
property
but you'd have to await that yourself somewhere, and I don't exactly know what the ergonomics of that would be 🤷
Thanks @NullVoxPopuli, I have it working with a poor man's version of that.
My Resource has a tracked isLoading
property that is updated when the fetch completes. I've added something to the constructor to call fastboot.deferRendering(promise)
if required, with a Promise that resolves when isLoading
updates.
It's clumsy but it works - Fastboot returns a DOM with fetched content in.
The example you have highlighted is more elegant so I will refactor around that, thanks so much for taking the time to look and share.
🙏🏻👌🏻🤩