Skip to content
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 Flickering with Render Mode Static #3975

Closed
mdmontesinos opened this issue Mar 11, 2024 · 19 comments
Closed

UI Flickering with Render Mode Static #3975

mdmontesinos opened this issue Mar 11, 2024 · 19 comments

Comments

@mdmontesinos
Copy link
Contributor

I just did a fresh Oqtane install (cloned the repo just now) and I noticed that the new Static render mode displays a lot of flickering in the UI.

I recorded a short video:

oqtane-flickering.webm

In the dev tools, you can see the new blazor enhanced navigation being used, yet there's quite a lot of flickering in the UI. Essentially, from the UI perspective it seems like I'm doing a full page reload instead of enhanced navigating, and it gets really annoying.

Also, and I believe there's no way around it because that's how Blazor works, but when crossing render boundaries such as editing the page you do get a full page reload?

@sbwalker
Copy link
Member

sbwalker commented Mar 11, 2024

@mdmontesinos there are a variety of different scenarios to consider when it comes to render modes...

  1. If you are NOT logged in to the application then all of the publicly facing pages and Html/Text modules are using only Static Rendering. This scenario is using Enhanced Navigation which means it is not doing full page reloads - it is using fetch/DOM patch. There should be no "flickering" in this scenario.

  2. If you login to the application as a host user, some components will be rendered Interactively - specifically the Control Panel and Module Actions menu. Also note that features such as invoking Edit Mode must refresh the page content. There may be some "flickering" in this scenario as the UI is comprised of both static and interactive components.

I guess the good news is that if you do not like the new behavior and want to use fully Interactive Render Mode, you simply need to change the Site Setting Render Mode option to Interactive. This will provide the exact same user experience as traditional Oqtane applications.

@sbwalker
Copy link
Member

I do not believe there is anything actionable in this issue report, so I am going to close it.

@mdmontesinos
Copy link
Contributor Author

  1. If you are NOT logged in to the application then all of the publicly facing pages and Html/Text modules are using only Static Rendering. This scenario is using Enhanced Navigation which means it is not doing full page reloads - it is using fetch/DOM patch. There should be no "flickering" in this scenario.

Yes, that's why I'm referencing this as an issue. I did a fresh installation of Oqtane, with no additional modules or anything, just the cloned code and I did get the UI flickering when enhanced navigating between pages in Static mode without being logged in. You can see this happen in the first part of the video. This does not happen with the new .NET 8 template for InteractiveNone, so I believe there's something happening in Oqtane.

  1. If you login to the application as a host user, some components will be rendered Interactively - specifically the Control Panel and Module Actions menu. Also note that features such as invoking Edit Mode must refresh the page content. There may be some "flickering" in this scenario as the UI is comprised of both static and interactive components.

As for this, I assumed that was happening so it does not worry me too much. However, the other case is quite relevant as the majority of users won't be logged in, yet will experience flickering.

@sbwalker sbwalker reopened this Mar 11, 2024
@sbwalker
Copy link
Member

Also note that the .NET 8 template is not a real Blazor application - it has no services, no data access, and a only a few simplistic components.

That being said, I suspect the StreamRendering may be causing multiple renderings of the UI. This needs to be investigated further - I already logged an issue with Microsoft related to this item... perhaps I will be able to speak to a Blazor team member at the MVP Summit this week to get more insight.

@mdmontesinos
Copy link
Contributor Author

Ok I will re-open the issue… but I am not experiencing the “flicker” locally and I can’t really see it in your video

Perhaps "Flickering" is not the appropriate term to use. What I mean is the nav bar is re-rendered on each page navigation, giving the user the impression that there's been a full page reload, instead of a smooth SPA-like behaviour where only the body is dynamically changing, which is the more or less the aim of enhanced navigation. Maybe this must happen in Oqtane due to the way it renders the nav bar and detects active routes. Also obvious to note, but it does not occur when the site is set to Interactive render.

@sbwalker
Copy link
Member

@mdmontesinos the one unique thing which the nav menu is doing is it is leveraging "attribute splatting" (https://learn.microsoft.com/en-us/aspnet/core/blazor/components/splat-attributes-and-arbitrary-parameters?view=aspnetcore-8.0#attribute-splatting) ie. it builds a dictionary of attributes and assigns it to the element at run-time. I am wondering if this approach causes problems with enhanced navigation.

@sbwalker
Copy link
Member

I demonstrated the issue with StreamRendering to Dan Roth at the MVP Summit and will be engaging with the Blazor team further to investigate the issue.

@mdmontesinos
Copy link
Contributor Author

mdmontesinos commented Mar 15, 2024

Great, thanks for the updates!

If there's an issue created in the asp repo please link it so we can follow.

@sbwalker
Copy link
Member

sbwalker commented Mar 16, 2024

@mdmontesinos I am curious if PR #4004 improves the Static experience for you. Basically it eliminates an HttpClient call in Routes.razor and I am wondering if the async/await behavior and latency of these HttpClient calls are causing the issues with the UI rendering.

You would need to test using only pages with HTML/Text modules - not Admin modules as most of them use HttpClient.

@mdmontesinos
Copy link
Contributor Author

@sbwalker I'm still experiencing the same "flickering" of the UI (perhaps a bit better?)

Here's a video of the issue with latest dev branch;

screen-capture.webm

Also, you can notice in the video that even when I navigate to the page that I'm currently at, I still get the "flickering" because the header is reloaded even though there should be enhanced navigation (and there are no changes to it).

Here's the console trace that starts when navigating to root page. In every page request, a request to the logo file is performed, which I believe could be causing the issue.

info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
      Request starting HTTP/1.1 GET http://localhost:44357/ - - -
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
      Executing endpoint 'Fallback {*path:nonfile}'
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
      Request starting HTTP/1.1 GET http://localhost:44357/api/Sync/00010101000000000 - - -
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
      Executing endpoint 'Oqtane.Controllers.SyncController.Get (Oqtane.Server)'
info: Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker[102]
      Route matched with {action = "Get", controller = "Sync", page = ""}. Executing controller action with signature Oqtane.Models.Sync Get(System.String) on controller Oqtane.Controllers.SyncController (Oqtane.Server).
info: Microsoft.AspNetCore.Mvc.Infrastructure.ObjectResultExecutor[1]
      Executing ObjectResult, writing value of type 'Oqtane.Models.Sync'.
info: Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker[105]
      Executed action Oqtane.Controllers.SyncController.Get (Oqtane.Server) in 0.3088ms
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
      Executed endpoint 'Oqtane.Controllers.SyncController.Get (Oqtane.Server)'
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
      Request finished HTTP/1.1 GET http://localhost:44357/api/Sync/00010101000000000 - 200 - application/json;+charset=utf-8 2.5239ms
info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2]
      Authorization failed. These requirements were not met:
      RolesAuthorizationRequirement:User.IsInRole must be true for one of the following roles: (Registered Users)
info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2]
      Authorization failed. These requirements were not met:
      RolesAuthorizationRequirement:User.IsInRole must be true for one of the following roles: (Registered Users)
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
      Executed endpoint 'Fallback {*path:nonfile}'
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
      Request finished HTTP/1.1 GET http://localhost:44357/ - 200 - text/html;+charset=utf-8 34.0347ms
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
      Request starting HTTP/1.1 GET http://localhost:44357/files/id/1 - - -
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
      Request starting HTTP/1.1 GET http://localhost:44357/oqtane-glow.png - - -
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
      Executing endpoint '/Files'
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[103]
      Route matched with {page = "/Files", action = "", controller = ""}. Executing page /Files
info: Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware[2]
      Sending file. Request path: '/oqtane-glow.png'. Physical path: 'PATH\oqtane.framework\Oqtane.Server\wwwroot\oqtane-glow.png'
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
      Request finished HTTP/1.1 GET http://localhost:44357/oqtane-glow.png - 200 63337 image/png 1.9177ms
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[105]
      Executing handler method Oqtane.Pages.FilesModel.OnGet - ModelState is Valid
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[108]
      Executed handler method OnGet, returned result Microsoft.AspNetCore.Mvc.PhysicalFileResult.
info: Microsoft.AspNetCore.Mvc.Infrastructure.PhysicalFileResultExecutor[1]
      Executing PhysicalFileResult, sending file 'PATH\oqtane.framework\Oqtane.Server\Content\Tenants\1\Sites\1\logo-white.png' with download name '' ...
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[104]
      Executed page /Files in 10.7383ms
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
      Executed endpoint '/Files'
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
      Request finished HTTP/1.1 GET http://localhost:44357/files/id/1 - 200 7963 image/png 11.7961ms

@sbwalker
Copy link
Member

I am not sure how the request for the logo would cause this - the logo is being served by the standard static file handler in ASP.NET - which is completely independent from Blazor component rendering. Enhanced navigation only relates to page markup - not how static assets are loaded.

@sbwalker
Copy link
Member

sbwalker commented Mar 17, 2024

I believe the "flash" is caused by the StreamRendering attribute in Routes.razor. However removing this attribute presents Oqtane from rendering any page content. This is the item I demonstrated to Dan Roth at the MVP Summit which needs further investigation by the Blazor team.

StreamRendering is only supposed to be used for long running async processes where you want to push some initial content to the browser to provide an initial UI rendering for the user... and then it pushes the rest of the content when the long running process completes. This all happens within the same page request. The typical example is when you want to call an external API which has high latency or is returning a large amount of data.

@sbwalker
Copy link
Member

@mdmontesinos the link to the issue is here:

dotnet/aspnetcore#54157

@sbwalker
Copy link
Member

@mdmontesinos my local environment does not exhibit the same behavior as yours...

Home.-.Default.Site.Firefox.Developer.Edition.2024-03-17.12-17-08.mp4

@mdmontesinos
Copy link
Contributor Author

mdmontesinos commented Mar 17, 2024

It's clear that yours displays a much better behaviour, almost just like .NET 8 Interactive None template, and I don't really know why. My Oqtane is a fresh install with latest dev branch. Might it be related to network or hardware speed?

However, notice that when navigating from "Home" to "My page" in the 16 second there's no flash, but when navigating back to "Home" in the 17 second, the UI does flash. That's the only time it occurs in your video, so it's an inconsistent behaviour...

EDIT: I also tested Firefox and Chrome in incognito mode to discard anything happening with plugins or browser and it stills displays the same UI flashing.

@sbwalker
Copy link
Member

@mdmontesinos the main reason I posted the video is to demonstrate that I can’t reproduce the issue locally - which is why I closed this issue originally. However I do believe we need to get to the root of this problem. It would be helpful if others could share their own experiences to indicate which of us is the outlier scenario. @thabaum @leigh-pointer @zyhfish

@thabaum
Copy link
Contributor

thabaum commented Mar 21, 2024

@sbwalker I think after exploring the HttpClientFactory we should revisit this. It just does a page refresh pretty much each time, not saving the enhanced navigation information needed to make the app not "flicker". This is similar to a site like eBay for example, I can't find a site page there that does not "flicker"

If you have a ton of visitors like eBay maybe this is your solution, if you have fewer visitors and is just a basic small business website app... I think global interactivity is the way to go and if you can use Auto mode when possible and properly. Otherwise Server-Side SignalR is the way to go. It really depends on your server traffic and your server resources to determine which mode might serve best for the application.

Again I think after enhancing HttpClient to use the HttpClientFactory may help us here as well as with the ActionDialog issue potentially. I am not 100% sure how the blazor.web.js file stores client information in relation to these two areas, so it will be educational if it does have any impact in areas like this one.

This feels more like a per request issue and the blazor.web.js file context was just me speaking out loud little.

@mdmontesinos
Copy link
Contributor Author

I'm not sure what changed from when I posted this issue and now, but the UI flickering I reported does not appear any more. Navigation between pages now is really smooth and the header and nav sections do not flicker at all.

@sbwalker
Copy link
Member

sbwalker commented Apr 8, 2024

fixed in #4118

@sbwalker sbwalker closed this as completed Apr 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants