-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Replay is making my Angular app super slow #6946
Comments
Hi @mebibou, thanks for writing in! I'm afraid, Replay is always going to add overhead to your app, as rrweb (the underlying library we use to record everything that's happening) just needs to listen and react to so many events, DOM mutations, style changes, etc. We're right now working on performance overhead measurements, to better understand the overall impact. For instance, #6611 introduced the first version of them. We're still trying to improve here, as we've noticed that results seem to fluctuate and depend a lot on the individual apps. It's interesting that the impact is so noticeable in your app. Would you mind sharing a little information about it? For instance:
Lastly, I guess the thin you can try at the moment to mitigate the overhead would be to lower the sample rates of errors and sessions. If a session is not sampled (both entire sessions and errors), our integration doesn't do anything and there should be no noticable performance impact. Hope this helps a little. LMK if you have more questions :) |
@Lms24 thanks for the reply Our app does have a lot of interaction, and one part of it where the lag is very noticeable is a place where we have a dynamic form, i.e. the user can add more components, add some text, sometimes clicking on a button will open a dialogue, etc. so based on ReactiveForms. But even on simple pages where we just display a list of search results, the results took about 2-5 seconds to display compared to without the Replay you would barely see the loader. I didn't really perform any measurements as users started to complain the website was too slow to use so I simply disabled it. I don't think sampling would help, as it would still fall randomly on some users to have a horrible experience? An idea that I had though: is there any way to enable the integration, but have some way to turn it on/off at runtime? I am thinking in cases where the user has a bug, and it could "turn on recording" (with a disclaimer that everything will be slower when recording is on)? |
A wild guess here would be that maybe some validation logic is constantly updating the UI after an input? It's been a while since I played with Angular Reactive Forms but maybe the
Yes, you can start and stop recording manually. For instance, it might be possible to stop recording on these more complex pages. Furthermore, only recording when errors happen is supported ootb by the Replay integration: replaysSessionSampleRate: 0,
replaysOnErrorSampleRate: 1.0, // or a smaller value, depending on what you perefer: Note though, at the beginning of a session, we make a sampling decision based on the sample rates. If the session is sampled for errors, we'll still record all the time but only keep the last 60s of recording in the buffer. Hence, performance degredation is probably still noticeable. |
sorry missed that section in the readme, I will have a play with it when I can spend more time on this.
Yes but unfortunately, the more complex the page, the more the need to record the sessions! We do use |
@mebibou do you have a publicly accessible URL where this happens that we can use to test ourselves? I'm curious if it's form input related and if ignoring events on the inputs would help perf. |
One more question: What kind of change detection strategy are you using? |
We use Angular Material. In a tab group you can wrap a tab with
We are using the default change detection strategy. I'd also like to say replay is amazing. It's been a long time since software has delighted me this much. Kudos! |
We use the default in most places. We tried to use "OnPush" but we had many problems with components no re-rendering anything and as the application is quite complex, it would take too long to debug/rewrite everything so OnPush is applicable. |
Potentially, yes. Probably not the default CD strategy per sé but the combination of it with complex apps, is my best guess. Generally, because rrweb records every single DOM mutation, style change, etc, my guess is that the default CD strategy causes quite a lot of these (including unnecessary ones) which might slow things down. |
I'm seeing something similar in my Angular app where I'm using Bootstrap instead of Angular Material for my tabs. I have a tab that has a decently large table of data (~500+ rows) and when Replay is enabled and I scroll down/up quickly it completely breaks the UI (text/buttons/content randomly disappear) and the page won't respond to the point of chrome eventually crashing. When I turn replay off, the table works fine. I've played around with the amount of rows that will break the UI and it looks like it starts to become unresponsive at around 200 rows |
Our angular app has dynamic forms and other complex UI/DOM stuff going on as well. However, in the past we have used other replay-like products in the past including hotjar, logrocket not to mention a few more. This is the only one that is producing serious performance penalties to our angular app to the point of us having to disable it. So there is some sort of extra inefficiency built into it whether by design or not that is producing this overhead, and until such overhead is brought down to a manageable level we will not be able to use replay going forward. |
Hi @jpike88, I'm sorry that you're experiencing this performance impact. I understand that this is a serious problem for you and we're working on improving performance. Our running theory is that the slowdown is caused by a spike in DOM mutations within a very short time period. We'll soon be able to detect these spikes to confirm our theory. Angular's default change detection might contribute to this spike, given that it is likely to update DOM elements that necessarily don't need to be updated. We'll keep you posted on further improvements and developments in this area :) |
This issue has gone three weeks without activity. In another week, I will close it. But! If you comment or otherwise update it, I will reset the clock, and if you label it "A weed is but an unloved flower." ― Ella Wheeler Wilcox 🥀 |
This issue has gone three weeks without activity. In another week, I will close it. But! If you comment or otherwise update it, I will reset the clock, and if you remove the label "A weed is but an unloved flower." ― Ella Wheeler Wilcox 🥀 |
I have also been seeing this issue as I've been integrating Sentry into our Angular app. I've done some digging into it and I believe I've found the main cause of the performance hit (at least in our case). It appears that rrweb is running a call to I've managed to restore the performance of our app by disabling the patching of Here's a screenshot of a profile from our app, when it's just sitting idly on a simple page for 4 seconds: And here's a profile of the exact same page sitting for 4 seconds, but with the |
Hey, For reference, could you share how you disabled this patching in your app? |
As explained here: getsentry/sentry-javascript#6946 (comment) the usage of `requestAnimationFrame` can lead to issues when working with Zone.js.
I opened a PR to hopefully fix this on rrweb side: getsentry/rrweb#150 |
As explained here: getsentry/sentry-javascript#6946 (comment) the usage of `requestAnimationFrame` can lead to issues when working with Zone.js. With this fix, where possible we should now use the `requestAnimationFrame` implementation from an iframe, if possible, and else fall back on just using `window.requestAnimationFrame` as before. We already do something similar in sentry-javascript to get an unpatched `fetch`: https://github.com/getsentry/sentry-javascript/blob/23ef22b115c8868861896cc9003bd4bb6afb0690/packages/browser/src/transports/utils.ts#L65-L71 so this should hopefully work fine!
Great work with the fix @mydea! Sorry I didn't reply in time. The way I disabled it was to globally disable the monkey-patching of the function by Angular, because we didn't need change detection to automatically run whenever RAF runs - but obviously that's not a feasible solution for many people. The iframe technique is clever, and will also mean that it'll work for other libraries that override the native implementation 💪 Sadly the performance is still not great on our application, but I did realise that we were using an outdated version of the JS SDK because we use the Capacitor plugin which is locked to v7.81 - and when I manually overrode this to get the latest version things did improve a bit, because of the rrweb improvements. |
Thanks for the info! yeah, updating to a more recent version of replay should improve performance a bit. we will work on further improvements down the line too! But it will be great to unblock this angular specific issue here 🙏 |
This bump contains the following changes: - fix(rrweb): Use unpatched requestAnimationFrame when possible [#150](getsentry/rrweb#150) - ref: Avoid async in canvas [#143](getsentry/rrweb#143) - feat: Bundle canvas worker manually [#144](getsentry/rrweb#144) - build: Build for ES2020 [#142](getsentry/rrweb#142) Extracted out from #9826 Closes #6946
The fix for this was released with https://github.com/getsentry/sentry-javascript/releases/tag/7.93.0 - please give it a try! |
As explained here: getsentry/sentry-javascript#6946 (comment) the usage of `requestAnimationFrame` can lead to issues when working with Zone.js. With this fix, where possible we should now use the `requestAnimationFrame` implementation from an iframe, if possible, and else fall back on just using `window.requestAnimationFrame` as before. We already do something similar in sentry-javascript to get an unpatched `fetch`: https://github.com/getsentry/sentry-javascript/blob/23ef22b115c8868861896cc9003bd4bb6afb0690/packages/browser/src/transports/utils.ts#L65-L71 so this should hopefully work fine!
Is there an existing issue for this?
How do you use Sentry?
Sentry Saas (sentry.io)
Which package are you using?
@sentry/angular
SDK Version
7.31.1
Framework Version
Angular 14.2.8
Link to Sentry event
No response
SDK Setup
Steps to Reproduce
Add the Replay integration to the Angular app. Without it the website is smooth, as soon as I add it it gets super slow continuously
Expected Result
Add Replay shouldn't impact performance so much, or it's basically becomes unusable
Actual Result
Everything is slow
The text was updated successfully, but these errors were encountered: