Closed slackermorris closed 9 months ago
I should read this article to better understand client directives.
I also think that WatchlistMovies
needs to be converted into a React component so that I might have a loading UI.
See how quickly the page loads without the WatchlistMovies
component being introduced.
What are the demands of the Watchlist list of movies component? It will eventually need client interactivity because I will update.
Think about having a sort of scratch pad to write thoughts down on and when you hover on the movie it shows all these different scrawls and that.
This component renders server side. Data fetching is serverside.
React too will be rendered on the server and passed down? Will the loading state be respected? I am little confused.
At this point we have a waterfall. I am not taking advantage of any part of the islands architecture.
THIS IS WORTHWHILE WRITING UP IN CONJUNCTION WITH OTHER NOTES
SSR data is fetched and then passed to the component, cannot do check to see if the code is running in the browser like:
Is it necessary that I SSR this component. Or can be it statically generated? The content will change because the user can add and subtract stuff from the Watchlist. I think I need to whiteboard this out.
I quite like this when a user loses internet connection.
If my page is rendered on the server then why is there a delay?
It just feels like the WatchlistMovies loads after the Search Panel. You can notice the jump between the loading of the two things here:
It seems like the fetch for retrieving the movies is causing this component to render more slowly. Perhaps something to do with the islands architecture?
☝️ Yeah, this does have to do with Islands Architecture:
These placeholders/slots contain the server-rendered HTML output from their corresponding widget. They denote regions that can then be "hydrated" on the client into small self-contained widgets, reusing their server-rendered initial HTML.
All notes can be elaborated upon here.
From this search:
Astro allows you to choose on-demand rendering for some, or all of your pages and endpoints. This is also known as server-side rendering (SSR): generating HTML pages on the server when requested and sending them to the client. An adapter is used to run your project on the server and handle these requests.
I should definitely sit down and watch this: https://www.youtube.com/watch?v=2ZEMb_H-LYE
OMFG I think I found it. I wonder why they don't advertise this:
Astro with server mode it is a little different. When you make a await async call on the server in an Astro component, all the components and markdown underneath that Astro component making the async call will be blocked until the async call is finished. While with NextJS server components you can have a server component that can make a await async call on server and it won't block components from rendering underneath it till it's finished.
James says as much here.
Astro ships the initial page load to the browser and then streams the results of asynchronous calls in the front matter, asynchronously as it receives it.
James says more information can be found from this stream.
It's almost like because it is streaming I would like to make use of something like we see with Suspense and be able to declare a loading component.
OK. So, one step at a time.
WatchlistMovies
astro component. I introduced the Astro Image component.
This is the Image Docs I am looking at.
This is why I need to add dimensions.
It seems as though the poster is delaying the rendering of the Watchlist
content proper.
I want the WatchlistMovie
to render. It has a bunch of content written about it. I then want the image to render.
Does Astro not support this?
Fuck it. What does it matter. The picture and remainder of the content should appear at the same time.
I don't think that Astro supports nested routes like how Remix does in offering parts of its page rendering before others.
Remixs' nested routes allows for:
In some web applications, the sequential loading of data and assets can sometimes lead to an artificially slow user experience. Even when data dependencies aren't interdependent, they may be loaded sequentially because they are coupled to rendering hierarchy, creating an undesirable chain of requests.
Remix leverages its nested routing system to optimize load times. When a URL matches multiple routes, Remix will load the required data and assets for all matching routes in parallel. By doing this, Remix effectively sidesteps the conventional pitfall of chained request sequences.
I think the main feature that I am missing is nested routes. Meh.
I hate how we get the momentary flash of the bounding box before everything loads.
It's like the HTML renders for the WatchlistMovie
, which is just a bounding box, and then we load what is needed for the MoviePoster
.
It is blocked by the MoviePoster
loading..... The MoviePoster
depends on the WatchlistMovie
being resolved first.
I hate the little flash when there is no content and we get this empty bounding box.
It's like it renders the minimum content and then knows it needs to also make a fetch call for the Movie poster and so then delays further rendering of the component. But I am sort of wondering why it does not render with the remainder of the content and then just zip the Movie poster in.
Same weirdness is that it only does this for the first entry in the Watchlist....
I don't want anything to render until I am ready for it. Is it possible to split them into siblings?
Fuck this is starting to annoy me.
What do I want as a solution?
I don't want the bounding box to show. I want things when they are actually ready.
It's like Astro renders the first component because it anticipates that we will stream results.
What happens if it does not need to fetch the Movie?
Even if the Movie Poster url is hardcoded we still get the momentary bounding box before anything else shows.
So, it is as though the image component itself has a certain height associated with it.
Why does the p-4
cause there to be an empty bounding box:
<div class="flex justify-center w-[50%] p-4">
<MoviePoster posterPath={movie.movieDetails.poster_path} />
</div>
Just the fact that something exists above is enough for it to anticipate something to render.
It is entirely because of the fetch that is happening in the MoviePoster
component. This delay means that everything else is delayed from rendering, which does not seem right at all.
Interesting if you swap the order of the content from the movie poster then you sort of get the rendering behaviour that we expect.
It's as though with SSR it is reading the HTML chronologically. It gets to the closing <div>
above the MoviePoster
and sends it to the page and then sees the MoviePoster
and so stops because it as async data requirements and this blocks everything else from being rendered and so this is why we see this momentary flash of the bounding box because SOME HTML has been rendered:
<div class="flex bg-grey-50 justify-between rounded-lg border p-4">
<div class="flex justify-center w-[50%] p-4">
<MoviePoster />
I definitely need to write this down somewhere. How can I solve for this?
This is the HTML that results in the flashing content scenario.
---
import MoviePoster from "./MoviePoster.astro";
const { movie } = Astro.props;
---
<div class="flex bg-grey-50 justify-between rounded-lg border p-4 gap-4">
<div class="flex justify-center w-[50%]">
<MoviePoster posterPath={movie.movieDetails.poster_path} />
</div>
<div class="flex-col w-[50%]">
<h1>{movie.movieDetails.title}</h1>
<h2 class="font-afterAllBoldSerif font-bold text-2xl tracking-wide">
{movie.movieDetails.release_date}
</h2>
<p class="indent-7">{movie.movieDetails.overview}</p>
<div class="py-10">
{
movie.movieDetails.cast.map((cast) => (
<p class="indent-7">
{cast.name} as {cast.character}
</p>
))
}
</div>
{
movie.movieDetails.genres.length > 0 && (
<div class="border-t-[1px] border-b-[1px] border-black flex flex-row gap-4 justify-center py-6">
{movie.movieDetails.genres.map((genre: string) => (
<p class="">{genre}</p>
))}
</div>
)
}
</div>
</div>
The solution is to move the request for the imageUrl
required by the MoviePoster
into the front matter for the entire WatchlistMovie
component. This way we don't get the WatchlistMovie
component unless we also have the image.
I mean the page is generated server side.