Hangar icon indicating copy to clipboard operation
Hangar copied to clipboard

Projects home page flickers when switching to tab from secondary project page (/pages)

Open lynxplay opened this issue 3 years ago • 0 comments

Observed/problematic behavior

When switching from a secondary project page (one that isn't the home page) to another tab (like the versions tab), the projects main markdown flickers up for a few frames.

Expected behavior

The last page should be shown until the versions are loaded and the switch can be rendered.

Steps to reproduce

  1. Create a project page besides the home page.
  2. Open it
  3. Click on the versions tab and notice a quick flicker.

Make sure you have poor internet or you actively added a delay to the version fetching as this can be hard to spot with a fast connection.

Other

A quick write up for the underlying problem:

The following is the issue in regards to <suspense>:

The project page's <ProjectPageMarkdown> are :keyed using the route.fullPath to properly re-compute the component on a route change leading to the expected page content. When a user navigates to the Versions tab, the <suspense> computes the needed components in the background while keeping the last known slot active, which in this case is the project page. However, it does so with the new route which now is /user/project/versions leading to an invalidation of the last <ProjectPageMarkdown> component as they no longer share the same key.

A new one is constructed and, because the route /user/project/versions does not have any parameters in the router (it is a direct link to the version), usePage requests the page at pages/page/${user}/${project} + (path ? "/" + path : ""), which is just pages/page/user/project for the /user/project/versions route. This leads to the small flickering of the homepage markdown.

Getting around this seems somewhat difficult as we render a <ProjectPageMarkdown> on the /user/project/versions in any solution.

We could hence try to keep a single <ProjectPageMarkdown> component alive and throughout the entire lifespan, simply updating its content, which would be the alternative to :key. This component however would also receive the /user/project/versions route, so we would also have to fix that route even returning a page so that the component can stay on its last state.

Another option would be to simply compute the key for the project pages differently. Specifically, if the route is a route on the /pages path, we can use that as a key and if it isn't, we use the back route from the routers history as a key. That way inside <Suspense>, the <ProjectPageMarkdown> in the project pages page would identify it is not run from its expected endpoint and use the last key used based on router history. As a quick side note, this behaviour is only needed on the [user]/[project]/pages/[...all].vue stuff, not every page markdown would be affected.

Neither are particularly clean so if anyone has a fun idea to throw at it, please do :pray:

lynxplay avatar Jul 24 '22 15:07 lynxplay