-
Notifications
You must be signed in to change notification settings - Fork 10.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
UI flicker in simple-auth example #17082
Comments
Managed to capture a higher framerate gif. Here's what it looks like when I refresh 3 times: Friendly ping @KyleAMathews , could you take a look at this? |
That's expected behaviour. Your browser receives a plain html file that is being hydrated on the client as described by you already. There is a roundtrip for the authentication or whatever your are doing on the client side that is different from the pre-generated file. That roundtrip costs time and is visible to you. Throttle your network and it will be even more visible. You can observe the exact same thing when you visit https://store.gatsbyjs.org/. Put something in the cart and reload. You will see the badge on the cart icon appearing after the page is loaded. In Gatsby Develop mode it might be just quicker due to the hot page reloading environment you have running but that's not what you are dealing with in production. Three options that pop my mind:
In the last bullet I mention SSR vs. SSG. I think SSR fits your expectation. It's the "classical" approach where you generate the output on the server-side per user request. Keep in mind that Gatsby does SSR too but only once during build time for all pages and of course without the individual user session at hand. That's why I like the term SSG. The lines between SSR/SSG and maybe caching are of course a little bit blurry. |
There's no network roundtrip in this example--it's just checking a cookie. That's why I was hopeful that there could be a Gatsby-based solution. I think it's pretty common to have an app that's "almost 100% static." Like in my case, I just want a navbar at the top of the page to show either a login button or a "your profile" button based on the presence of a cookie (which could be checked either on the frontend or backend). The site is otherwise completely static. It would be really nice if Gatsby could handle a situation like this without unpleasant visual artifacts. I recognize that this is difficult to do with pre-rendered pages, especially given Gatsby's commitment to being able to be served in a purely-static environment like an S3 bucket. But if a solution could be found I think it would hit a lot of use-cases that would otherwise push people toward Next.js. Maybe the For my part, I'm porting my app to Next.js. Which is a shame, since Gatsby has been great otherwise. Feel free to close this issue if desired. |
We should just fix the example. The general pattern is to delay rendering things like that until the client js is loaded. It's far less noticable then. @thomasjm would you like to PR the change? |
In other words, check if window is defined before rendering something to avoid rendering during SSR |
That solution is much less noticeable, but when I tried that on my own app I found it was still too noticeable to use on something as prominent as the main navbar that appears on every page of my site. I think I'm going to be putting my energy into the Next.js version now, sorry. (In addition to this issue there are a couple other places where more flexible SSR is attractive to me as well.) |
Have you tried gatsby-plugin-offline? This gets you around things as logged in & returning users load the site purely client side -- a lot faster than SSRing every time. |
Hmm...looks interesting. I'm not very familiar with service workers. It looks like going that route involves sacrificing IE11 support. It seems like a rather large change to make, and I suspect regular SSR fits my needs best. I'll have to read about service workers further, thanks for the recommendation! |
You know how Next.js allows you to augment a React component with a |
That doesn't seem any different than "traditional" React patterns - load something on mount and set a loading flag. On load, remove the loading flag. While the loading flag is set, don't render the component. Or just straight up Suspense. My point is, this is not something Gatsby should implement but should be left for the user to implement it the way they want it to work, let's not opinionate the core Gatsby. |
Hiya! This issue has gone quiet. Spooky quiet. 👻 We get a lot of issues, so we currently close issues after 30 days of inactivity. It’s been at least 20 days since the last update here. If we missed this issue or if you want to keep it open, please reply here. You can also add the label "not stale" to keep this issue open! As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request. Check out gatsby.dev/contribute for more information about opening PRs, triaging issues, and contributing! Thanks for being a part of the Gatsby community! 💪💜 |
Hey again! It’s been 30 days since anything happened on this issue, so our friendly neighborhood robot (that’s me!) is going to close it. Please keep in mind that I’m only a robot, so if I’ve closed this issue in error, I’m As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request. Check out gatsby.dev/contribute for more information about opening PRs, triaging issues, and contributing! Thanks again for being part of the Gatsby community! |
Description
The simple-auth has an undesirable UI flicker when the app is built and used.
Based on whether the user is logged in or not, there is a piece of text that either reads "To get the full app experience, you’ll need to log in" or "Logged in as Jim (jim@example.org)! log out".
But when you load the page as a logged-in user, there's a brief flicker where the logged-out text is seen. (I tried to take a gif of this but it seems to happen a little too fast to easily capture--it's clearly visible to the eye though.)
I suspect the problem is the following: once a Gatsby site is built, it has already statically generated the pages. Since the app is in the "logged-out" state when the site is being generated, the logged-out text gets baked into the app. The logged-in text doesn't have a chance to render until the page is already loaded in the browser and the wrong text has already been seen.
I'm having this exact problem in a real app. One workaround I've tried is to make the element invisible during the logged-out state, so that it doesn't render at all until there's a React render in the browser. But this isn't very satisfactory, because then the rest of the page renders instantly and then the login status text appears a heartbeat later.
I'm really hoping there's a way to combine statically rendered pages with login/logout or similar state and have the page come up without a flicker. If all else fails I guess I could render two entire copies of my site, one logged-in and one logged-out...
Steps to reproduce
git clone git@github.com:gatsbyjs/gatsby.git && cd gatsby/examples/simple-auth
npm install
npm run build
python3 -m http.server 8080
, open localhost:8080 in a browser, log in as the app suggests and try refreshing the page.Note that the problem does not occur in a
gatsby develop
environment, but only once the site has been built.Expected result
There should not be a UI flicker. It should load immediately with the correct text.
Actual result
It flickers.
Environment
The text was updated successfully, but these errors were encountered: