framesurge / perseus

A state-driven web development framework for Rust with full support for server-side rendering and static generation.

Home Page:https://framesurge.sh/perseus/en-US

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Page transition jolt with long content

arctic-hen7 opened this issue · comments

This issue is reporting a bug in the code of Perseus. Details of the scope will be available in issue labels.
The author described their issue as follows:

In the demos/full_page_layout example, the page transition between / and /long (and vice versa) results in a substantial page 'jerk', for want of a better word. If one repeatedly goes between the pages, there's no problem, but waiting a few seconds before navigating delivers this jolting effect. Perseus now directly renders new content with sycamore::render_to or sycamore::hydrate_to, which implies there's an issue with integrating appropriately with CSS immediately when this occurs? This may not be a Perseus bug...

The steps to reproduce this issue are as follows:

See MRE (demos/full_page_layout example in the repo).

A minimum reproducible example is available at https://github.com/arctic-hen7/perseus/tree/main/examples/demos/full_page_layout.

  • Hydration-related: false
  • The author is willing to attempt a fix: true
Tribble internal data

dHJpYmJsZS1yZXBvcnRlZCxDLWJ1ZyxhdXRob3Itd2lsbGluZy10by1pbXBs

@lukechu10 would you be able to shine any light on this? (Note: it occurs with and without hydration.)

commented

It's a FOUC (Flash Of Unstyled Content). If you go into the browser devtool's network tab, you can block the style.css and then the issue is solved. The elements already have some inline styling so that is shown first before the css file is loaded.

I think the problem is that when navigating, perseus replaces the entire <head> and not just the dynamic part. This causes the style.css file to be re-fetched. I think the intended behavior should be that the static part provided by the index_view should never be modified.

Also there is another "jolt" when loading the page. This jolt seems to coincide with the addition of the route announcer. This might be a problem with the CSS and therefore adding a new node changes the behavior of the CSS selector.

commented

Also there is another "jolt" when loading the page. This jolt seems to coincide with the addition of the route announcer. This might be a problem with the CSS and therefore adding a new node changes the behavior of the CSS selector.

Actually, that's because the SSR-ed HTML is for some reason different from the hydrated HTML. There is an additional <div> around the <header> once the HTML is hydrated.

Perseus doesn't actually replace the whole head in content, but in terms of mechanics it does. That can probably be faiy easily fixed, since the delimiter functionality of what not to replace is already built in.

As for the initial load part, that's just because we can't put the dynamic view inside the router at the root yet. I did reflect that in the server side HTML at some point, though I seem to have removed it.

A plan of action then would be to add that div back and modify the head replacement logic on the client side to not delete and re-add elements that shouldn't change. I'll get on with that today.

Greatly appreciated, @lukechu10 !

Intriguingly, this seems to go away when just fixing the issue with the extra <div> not being provided by the server...

commented

Intriguingly, this seems to go away when just fixing the issue with the extra <div> not being provided by the server...

Yeah that's because the CSS styles differently depending on whether the div is there or not.

That would make sense on the first load, but in subsequent loads, the render is direct to that <div>... Am I missing something really obvious here?

The old head delimiter comment has now been replaced by a <meta content=""> element, which can be used as a marker to delete anything after it and replace it, avoiding any interaction with the static content before it that's shared between all pages.