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
4-10 seconds delay between navigated component's Constructor and ngOnInit() #18816
Comments
[wrong information here!] I can confirm this issue, and also report that the problem is in Angular v. 4.2.6, with two router related fixes:
[updated information] Actually the 4.2.0 is the broken version, so there has to be something that's different between 4.1.3 (last working version) and 4.2.0 (first broken version). All prior versions, including 4.1.3 works for us, but 4.2.0 is broken for some of the links. Constructor for the new component gets called when an ordinary Most of our links are working just fine, but there are some links that almost 100% consistently fails on Angular 4.2.0 and newer (tested versions include pretty much all Angular2 alpha/beta/rc and release versions, and eg. 4.1.3 and broken versions 4.2.0, 4.2.5, 4.2.6, 4.3.1 & 4.3.5). Our application is rather huge, and I can't think of a way to reproduce this on plunker. At least these broken links are addressing a sub route inside a lazy loaded module, and they happen to have query params with them. EDIT: IMPORTANT: I really don't understand how I got it "working" with 4.2.5. As I tested today, all versions from 4.2.0 are affected, and last working version is then 4.1.3. Probably some of the caches were not really cleaned during the test with 4.2.5 |
Btw. we are not using Google Auth or similar. And we do have async ngOnInit methods, though the problem persists also when all async ngOnInit calls where made non-async. Also the behaviour for us was that the old routed component stayed on the screen, but just taking the right half of the We do have guards for our "application level" or "module level" routes, but not any additional route guards for these particular sub routes. Links in guestion were inside one single guarded route. As an additional note: it doesn't matter whether our ES output version is ES5, ES2015, ES2016 or ES2017 (which is otherwise somewhat broken still with Zone.js). Currently working combination we have is ES2016 output with Angular 4.1.3. |
@rvalimaki do you have |
@tytskyi the link is inside our internal "grid" component` (kind of datatable), that happens to be |
@rvalimaki What i am thinking - is that when router navigates to component - change detection does not happen. But then, in 4-10 seconds you touch something on the screen that triggers change detection on the whole app. But this is only my guess |
@tytskyi I started trying that immediately after your first comment, but our app takes some ages to build... But now when I have Angular 4.3.5, and that particular "Grid" component with ChangeDetectionStrategy.Default, those links are unfortunately still not working correctly. |
@tytskyi I changed now all the remaining OnPush modes to Default on that lazy loaded module AND all the modules it does relate anyhow, but unfortunately the problem still persists. I agree that change detection is related to that, and the "4-10 seconds" as described by @kkotak pretty much seems to be determined from external change detection changes. Eg. we have a sockjs connection with a heartbeat, and every time the heartbeat comes (eg. every 10 seconds or so), the routed component fixes itself immediately. Those being said, I could probably overcome this problem by not using EDIT: I was wrong, 4.1.3 is the latest working version, so 4.2.0 and later are not working. |
@rvalimaki could you try to use https://angular.io/api/core/ChangeDetectorRef#markForCheck right in the constructor of the problematic component? Maybe in combination with This does not help to solve the problem, but at least we proof this is problem of change detection |
@tytskyi thanks, I tried that already last week, but calling changeDetectorRef inside the constructor resulted in fatal errors on Angular, effectively breaking the application. I'll try again, using setTimeout() this time. |
I can confirm that we see the same behavior as @rvalimaki of the old routed-out component staying on the screen despite the fact that ngDestroy was called on it. Also we're not using onPush for the routed-in component. |
Thanks @tytskyi Indeed, calling ChangeDetectorRef markForCheck() + detectChanges() "fixes" the situation:
Without setTimeout(), everything breaks. One of the problems with this workarounds is that we would need to repeat this in pretty much all components that can be possibly navigated to, which is plenty of components. |
Confirming that the workaround suggested by @rvalimaki also 'fixes' the issue on our end. We also have the same concern over propagating the workaround across the app to multiple components. In our case, the routed-in component also relies on the data retrieved in the ngOnInit() method, hence even though the component is rendered, the data it relies on still takes the same long time to render. We wouldn't want to move all that code from ngOnInit() to the constructor. |
Yeah, it is not the fix. It was just a bit of investigation... |
Could be related to this #16883 (somehow not listed in |
After adding this workaround to only 58 most likely navigated "main page components" (that fortunately shared a common ancestor class) things seems to work pretty smooth for now... I'm eager to help for debugging the actual issue more when someone investigates this issue. Just drop a note. @tytskyi: spot on! #16883 seems to be the culprit. @vicb probably knows how to mitigate this issue. |
It turns out to be a lot of workaround for us. @tytskyi - do you recommend we revert back to 4.2.5? |
@kkotak i cannot recommend to downgrade or upgrade, since i am just the user of angular. What i would recommend is to try to reproduce the same problem on the very minimal code so that it is easier to debug. However this does not guarantee that problem will be fixed immediately... |
@kkotak do you happen to have lazy loaded modules on your code? And are those non-working routes subroutes of said lazy loaded modules? |
@rvalimaki No we don't have lazy loaded modules in the app. |
@kkotak I got it wrong, it's 4.1.3 that's the last working version. Versions 4.2.0 onwards are broken. |
Well, it seems that after navigating to a component using that change detection workaround, the sub routes of that component do have similar problem still, and it doesn't go away using the same workaround for those sub route components (there are plenty of them!). This time, when our sub routes are in "tabs" that you can click multiple times, the problem seems to be actually worse, since by clicking those tabs several times, you get multiple empty components under router-outlet like that:
After some time, when some other change detection happens somewhere, these components are gone and replaced by the actual one. Needless to say, this situation kind of sucks, and we have to revert to Angular version 4.1.3 for now. Ps. we don't use observables unless they are really needed. We are using Promises with async/await for our data retrievals & also for our guards, since these are much more easier to use for our C#.NET developers that are trying to grasp TypeScript & Angular. TBH the async/await syntax is more clear for everyone other too. Just thinking if this is one of the many possibilities that could make it so that our routed components are not initialized as they should be. |
Thanks @rvalimaki for the updates. I also confirm that 4.1.3 is the last working version. I am a bit surprised that the issue has gone unnoticed for so long by the Angular community. Makes me want to think that there must be something uniquely wrong with our design. I also confirm that the workaround just kicks the can down the road to other components and MdDialog components, which show up empty. Our first hunch was that the issue might be related to the subscribe handler from where the navigate() call is made, but even after trying various alternatives and unsubscribes, etc. problem still persists. Interestingly, in our case, if the workaround is not used and if you accept the first delay in navigation, the rest of the components, dialogs, etc. work just fine. In other words, the problem seems to only occur once. I'm really hoping someone with the knowledge of the inner working of this area, would take a look. Downgrading back to 4.1.3 is a really painful path due to other 3rd party dependencies. |
Closing as no repro. |
We're also seeing all kinds of weird issues with change detection as of late. Even had to do ".detectChanges()" a few places that makes no sense - in places that used to work just fine. Currently I'm experiencing the same issue as OP: A routed component doesn't initialize until I cause a few other events. I'll try the constructor workaround. EDIT. EDIT2:
|
@larrssn I'm afraid, that this constructor workaround just leads into bigger problems. From now, I suggest downgrading to 4.1.3, as it's the last working Angular version. We have had also other change detection related problems with versions > 4.1.3, so we are currently staying on 4.1.3. Now we are way too busy to get our applications released, so we cannot investigate this problem for now. Hopefully someday we can have the time to construct a working Plunker demo of this problem to @vicb to investigate. Anyway, it seems that there are at least 3 companies having this problem. @larssn do you happen to use async/await or promises on your code, or do you use observables instead? |
@rvalimaki This particular project has no async/await in it (which I believe gets transpiled out anyway), and mostly Observables instead. I tried downgrading to 4.1.3, but couldn't figure out the correct mix of dependencies to avoid weird compiler specific errors. Our workaround is sufficient for now. 👍 |
I have also faced this behavior. Following workaround works for me:
Very similar to @tytskyi suggestion. I know that putting zone inside timeout may look weird. This is my result of trial and error process. Looks like this task has to be put on queue first and then wrapped inside zone. Caveats:
changed to
Looking forward to get it sorted. |
"Looking forward to get it sorted." Well, without working Plunker sample and this bug affecting only 3 companies so far, it's not going to get solved, and that's also the reason the issue closed for now. No assignees on this issue as well. We are sticking to working version 4.1.3 until we have enough time to investigate more on this issue. In some distant future, maybe. |
Same problem here... in my case this behaviour just happens when I'm logged with google auth, when logged with firebase email/pwd I have no delay.
|
I have the exact same problem as @sidleal. I have a workaround in the component in which a router event is started |
It would be nice to have a real fix for this as we also have seen this. In our case we are using this.router.navigateByUrl(relativeUrl) but see the exact same behavior. Is the issue to get it fixed a working sample or the number of people seeing the issue? The Solution marekozw posted here worked for us. I posted it below for reference. Other solutions posted here worked but had the issue where sub component loading was also delayed. constructor ( Thanks marekozw this was a big help! |
Which Angular version you are using? I just tested with Angular 5.0.0 and somehow links and router-outlets seems to be magically working, at least until we got the infamous "EXCEPTION: Expression has changed after it was checked" ((. After that, all router-outlets will duplicate components when navigated to. |
We have recently moved to 5 to try to get past the issue. I am trying to construct a simple example trying to duplicate our situation. I will let you know if I am able to dup it. |
Hi Guys,
The interesting thing is that if I click on the link that is on a visible grid row it opens properly but if I scroll down the grid and then click on the link it doesn't load the component properly. The proposed workaround by marekozw works properly on my side. I will try to reproduce the issue in a runnable sample maybe next week if I have some time. Thanks ! |
Hi, I am having exactly the same problem, the workaround worked for me also. @danail-vasilev, I am in the same situation as you, using that grid component bugs the navigation. Did you find any solution yet? Thanks! |
Hi @cfacello, |
@danail-vasilev thanks for the answer. Anyway, I searched a bit forward and found something important: |
I submitted a new bug related to this with a demo app - #23697 |
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. |
I'm submitting a...
Current behavior
Initial load of the module happens quickly but, when navigated to a route, the constructor of the destination component is also called in a timely manner, but the ngOnInit() method is not called for another 4-10 seconds. This happens every time and with not just one but all components that are called using navigation.
Expected behavior
This issue only surfaced when I upgraded Angular from 4.0.1 to 4.3.4. No code was changed in the app.
Minimal reproduction of the problem with instructions
I'm unable to create a plunker to reproduce this issue with shell code. If someone can shed some light on what happens between the component's constructor being called and ngOnInit() being called, I may be able to debug this further.
EDIT- Notably, the delay is observed right after processing Google Auth response that is processed by a Service, which then calls router.navigate() to the component in question.
What is the motivation / use case for changing the behavior?
The motivation is obvious. The delay is not expected behavior.
Environment
Production code is built using the following command -
node --max_old_space_size=8192 ./node_modules/.bin/ng build --aot --prod
The text was updated successfully, but these errors were encountered: