-
Notifications
You must be signed in to change notification settings - Fork 481
Cannot find a way to achieve a smooth transition to client app #1184
Comments
This is essentially what preboot does (when it works). I'm assuming you've also tried enabling initialNavigation in your Beyond that you likely need a creative approach, and a good place to find that is on Gitter or StackOverflow. The problem here is that this is a known quirk of Universal right now, as we wait for hydration in the post-Ivy world. But it's not exactly an "issue" since there are known methods for overcoming this, even with apps of complex sizes and shapes. I wish I could offer more, but again this is not exactly the best place for support of non-issues and non-feature requests. |
@CaerusKaru Thank you for your reply!
Yes I've already tried, but I haven't tried it in combination with Preboot, thank you for reminding me. I assumed it was a useful solution for CSS purposes, I didn't think it would have an impact with Preboot, is this the case? I'm not using StackOverflow or other platforms because first of all I think having the opinion of members/collaborators directly would have been better (and faster) since this is maybe THE main "issue" a lot of people have with Universal (from my point of view, obviously). I'm a consultant and this is a recurring topic in every team I've seen which uses Universal. You said that:
What are you referring to? Which known methods are you talking about? Don't you think that since this is a quirk of Universal we could be more clear about what these methods are? I think it would really really help a lot of people :) We've made big steps forward with developer experience in many points, also the official Angular documentation page about Universal was improved, but I feel that the docs are missing something, some guidance, some "Ok, you learned how these packages work, now these are your options if you're having these problems", something like the the "gotchas" that we already have a page for. It's not a "StackOverflow type of guidance" I'm talking about, I don't know if I was clear about this slight difference. It's more about best practices and real-world recurring problems and scenarios. Just as an example, a lot of people think that now that we have I hope I haven't bored you with this wall of text! What do you think about it? Could we improve the docs and make more clear which are the best practices and which are the "known methods" for overcoming these issues? I'd be glad to help too, if you need it. PS. Also, I forgot about lazy routes: could it be that using lazy loading causes the blank page to last longer? If this is the case, is there a way to make Angular load the lazy module and THEN rebuild the DOM? Or maybe this is already happening and my eyes are wrong? :) |
setting initialNavigation to 'enabled' basically does what you described towards the end - Wait for lazy loaded route to be ready before swapping in the client rendered DOM so as to avoid a flicker due to empty router-outlet in the lazy loaded route. |
@vikerman Thanks, I'll try again hoping something chages, I'm sure I've tried it not so long ago in the same project and nothing seemed to change, I'll pay more attention this time :) What do you think about making a little effort in order to have a better documentation for things like these ones? Again, "initialNavigation" is one of those things that you find only through issues, even the official Angular docs only say "Disables the initial navigation", nothing more. I'd be really glad to help, It would be great if we could gather some people and have some sort of brainstorming to identify common problems and solutions :) |
Same issue here. The problem is almost unnoticeable on pages with ~
@CaerusKaru, could you provide some links or keywords to these methods, please? Here are some related issues I've been reading the last two days:
P.s. I use |
So I tried to use Here is a commit I made to fix flickering using Try it out and give me some feedback, please. The only issue I have now is a mobile view: // app.routing
imports: [RouterModule.forRoot(routes, {
// ...
initialNavigation: 'enabled'
})], // app.module
imports: [
// ...
PrebootModule.withConfig({ appRoot: 'app-root' })
],
// ...
providers: [
{
provide: APP_INITIALIZER,
useFactory: function(document: HTMLDocument, platformId: Object): Function {
return () => {
if (isPlatformBrowser(platformId)) {
const dom = ɵgetDOM();
const styles: any[] = Array.prototype.slice.apply(dom.querySelectorAll(document, `style[ng-transition]`));
styles.forEach(el => {
// Remove ng-transition attribute to prevent Angular appInitializerFactory
// to remove server styles before preboot complete
el.removeAttribute('ng-transition');
});
document.addEventListener('PrebootComplete', () => {
// After preboot complete, remove the server scripts
setTimeout(() => styles.forEach(el => dom.remove(el)));
});
}
};
},
deps: [DOCUMENT, PLATFORM_ID],
multi: true
}, |
I tried with The problem I have with initialNavigation, is that now, since the initial navigation is performed before the main component is bootstrapped, a lot of my router-related observables (ex. Still, I need some testing to see if this behavior is acceptable and I'd leave this issue open for my previous requests regarding the docs. I hope to receive some feedback by members/collaborators. |
We are adding Issue #1200 |
@vikerman adding I think it can't be the right solution for getting a smoother transition. Right? |
Hi Guys, any idea why |
@UserGalileo angular/angular#32571 was opened to report this just a couple weeks ago. In response to that, PR angular/angular#32707 adds the In addition, in PR angular/angular#32702 @jbogarthyde updated the |
@BruneXX that sounds like a related, but different issue, can you please open a new issue with a reproduction? |
As I mentioned in #1200 (comment), it seems like the SSR Guide needs to be updated to include information and examples for both Preboot and However, after reading this and the other related issues, it's not clear that the best practices or recommendations have fully solidified here. Does anyone know of any blog posts that dive deeper into this and provide some recommendations? The Preboot library has a similar issue and a reproduction that shows that both Preboot and |
Unfortunately, although As I said, router-based observables behave differently. Router-based libraries don't work. Guards run in a different order (ex. I am authenticating or checking for tokens in AppComponent but guards don't wait for AppComponent to run), so I don't think we can say that this is the solution to all the problems. Honestly, after weeks, this experience is really driving me crazy... I don't want to sound polemic, this is just my experience. I don't know @Splaktar , what could we do? I think a solution should be found internally in order to make things behave like |
@giacomo |
About this flickering, my approach for now is to put a huge page-size loading overlay until components are rendered correctly on client side, - only benefit here is that the page is still crawlable by no-javascript SEO bots. I hope we can have a better solution for this in the future so we can also benefit of a smoother page load. |
I've got a smooth transition, made with prerendering and preboot combination. Github.com/rickvandermey/angular-starterkit I use SSR to create static html files for serving and preboot comes in for the transition |
@UserGalileo - We currently don't understand the issue to provide a solution. Is there a way you can create a smaller repro of the issue and share a test repo? Thanks! |
@zjcboy no there is for me no solution at this point - as I said |
@giacomo - Is it possible to share a small repro of the issue? |
@vikerman What would the test repo be like? What do you want to see that you cannot understand now? As I and others said, router observables will stop working: simply try using |
I have different experiences. I have a route animation,when I remove it, the flicker disappears |
I have an introduction animation in my app, so when the app is being bootstrapped, the animation reoccurs. Is there a way to prevent it? For now, I added a loading spinner until the app is bootstrapped, but that's not a good solution. |
So I've created a "repro repository" with angular 9. But it seems that the problem doesn't affect angular 9. Could some one look in my code or tell me if the problem still exists. @UserGalileo can you confirm? REPRO Link: https://github.com/giacomo/angular-initial-navigation-repro Since the https://github.com/gilsdav/ngx-translate-router isn't fully compatible to angular 9 at the moment I can't install it. Here are some logsdev - default
dev - initialNavigation: 'enable'
prod - initialNavigation: 'enable'
Using:
|
I can conform it's still happening in Angular v9 - tested the flickering using Flex Layout |
It's happening in my Angular 9 project as well. Using Angular Material. |
@nicholas-davis could you please create a branch to my repo so that the angular team could reproduce it. Thanks. |
It's happening with Angular 10 and Angular Universal 10 too, I don't have lazy loaded modules hence |
Still have this issue with angular9 |
@vikerman |
@puneetverma05 this is probably the guard returns an boolean promise or observable boolean. Return an URLTREE should avoid the homepage |
@rickvandermey apparently, The issue was related to the ngrx select |
This issue still exist, in my case I have a landing page when first visit, landing page is visible for about 100ms, it is really bad ux for first time visitors of the app. Already tried solutions like Transferstate but in my case does not meet my expectations to solve the issue. My landing page do not have any XHR request. I also tried the TransferHttpCacheModule, I notice that first visit, sometimes it loads correctly without the glimpse of landing page, and sometimes it lessens the flicker amount of time for about 20ms but still I can see a glimpse of my landing page, after that it somehow fix my issue, but when I clear my cache, it returns back to previous state which the landing page is visible for about 20ms. Also tried Preboot as what others is suggesting, but it is not suitable for my app, I have a mat-progress-spinner which acts as loading, when preboot is enabled and I hit F5/refresh my loading icon freezes for a while, it does not animate, which I think is very ugly and after about 1sec it goes back to normal state (app is working as usual like normal angular app). I'm actually stuck here and I can't just leave it as it is. |
This problem still perists in Angular 13. I created a repro: The steps to create this repo were:
To reproduce the problem, please follow these steps:
You will see the server-side rendered version. Angular is not loaded because of step 5 above. The content of the lazy component is present in the DOM as expected:
You'll notice the dev tools has paused execution in the lazy.component. The page will be blank at this point. You'll see that that the The fact that the server-side rendered content of the router-outlet is removed while the My last attempt to solve this was to detach change detection, as I figured the component was being rendered in a blank state before data was read. Since the old HTML is already gone when the constructor is executed, tweaking the change detection is no use. I would expect the old HTML to be replaced only when the new component renders the first time (ie. after init lifecycle hook) |
@webberig did you try |
Yes, this is already added automatically when you add universal. If you add a breakpoint as described in my previous comment, you will see that the server-side html is gone. Your app may just be small and fast enough to not notice a flicker, but it's there. I got much improvement after adding preboot, though. |
This should be fixed with the current hydration efforts. Let's keep tracking such issues in angular/angular#23427 |
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
Hi everybody!
I've spent some hours on this platform hoping to find a solution to my main problem with Universal (and SSR in general), I've read a lot of issues but I just can't find a solution. This post may seem a duplicate of many others, but I want to take a different approach: I'd like to ask some questions, hoping to get some useful info from this issue, and hoping it won't be closed and marked as duplicate because it's not my intention to duplicate issues. If what I describe here is the desired behavior of Universal or it's something that you're dealing with right now, perfect, I'm not trying to change things or report bugs.
From what I know:
This behavior causes a slight flicker, because the whole body is discarded (leading to a blank page) and re-rendered (leading to the "old" server-generated page, which is in reality the client app). There are a large number of issues about this "flicker", but it appears that many "flickering issues" may be caused by CSS being re-appended to DOM after the transition. This is not what I'm talking about as I don't have any problems with styles. The "flicker" I'm referring to is the HTML being re-rendered.
The best case scenario is that we have a simple page with a relatively easy DOM being rendered. In this case, the flicker is almost unnoticeable.
In my case, my view is a bit complex. The rendering process can take some time because we are talking about tens of items, with subitems, and a lot of css. In my case, this flicker is unbearable, it just takes about 2 seconds for the page to become blank and back again. I'm just testing it with my computer, I don't even want to think about mobile devices :D
This behavior is especially noticeable with lazy routes. If you try the universal-starter, and if you navigate to the "lazy" route, put Chrome in "Slow 3g" mode and refresh the page clearing the cache, you can clearly see the problem. The same problem is unnoticeable in the main route (maybe because it's simpler? Or maybe it's because lazy routes make this flicker last longer?).
This is my problem. My page is not huge, but it's "slightly complex" and this flicker makes the Universal app unusable. I ask you: what are my options? Am I thinking/doing something wrong? I'm seriously thinking about using a loading spinner to hide the page until the client app has bootstrapped, but it's my last option since my app will be useful for SEO purposes but the user won't see anything in the meantime.
I have also tried using preboot (just the default configuration) which says that it helps to make the transition smoother, but nothing happened.
I asked myself if it could be possible to make the client-app bootstrap in a hidden div and wait for it to be rendered before destroying the static HTML, but I didn't manage to get it right and I'm unsure if it would solve the problem.
Thank you so much for your patience and I hope this issue can make things clear for other people too, and hopefully solve their problems :)
The text was updated successfully, but these errors were encountered: