posthog-ios icon indicating copy to clipboard operation
posthog-ios copied to clipboard

PostHog's Session Replay feature degrades Google services performance

Open katcinskiy opened this issue 9 months ago • 35 comments

I noticed that Google Street View and Google Maps are lagging when PostHog's session replay is active. Every time a screenshot is captured, there's a noticeable drop in frame rate that decreases the overall smoothness of Street View navigation.

I've observed that the smaller the config.sessionReplayConfig.debouncerDelay value, the less smooth the panorama becomes, so probably this is the root cause.

Here's my configuration:

let config = PostHogConfig(apiKey: "", host: "https://eu.i.posthog.com")

config.captureScreenViews = false
config.captureApplicationLifecycleEvents = true
config.sessionReplay = true
config.sessionReplayConfig.screenshotMode = true
config.sessionReplayConfig.captureNetworkTelemetry = true
config.sessionReplayConfig.maskAllImages = false
config.sessionReplayConfig.maskAllTextInputs = false
config.sessionReplayConfig.debouncerDelay = 1.0
PostHogSDK.shared.setup(config)

I didn't experience it with SmartLook session replay.

katcinskiy avatar Mar 23 '25 04:03 katcinskiy

Hey @katcinskiy, thank you for flagging this. I'll take a closer look and try and identify the bottleneck in the snapshot rendering pipeline. In the meantime, if you can attach a sample project with a screen that includes a Google Maps showcasing the lagging issue it would really speed things up for me 🙏

ioannisj avatar Mar 24 '25 12:03 ioannisj

@ioannisj sorry for the delay. Sure I will provide you example with panorama view. Please replace <gms_key> and <posthog_api_key>

google-streetview-test.zip

Here is the screencasts WITH post hog and WITHOUT, in PostHog version you can see some glitches:

https://github.com/user-attachments/assets/a95de077-dbf0-4a6b-811b-d07384d8ed15

https://github.com/user-attachments/assets/df5d69f1-8b30-4d7b-90c8-71dcb3584bdf

katcinskiy avatar Apr 27 '25 13:04 katcinskiy

Thanx @katcinskiy! I'll have a closer look and revert soon.

ioannisj avatar Apr 27 '25 14:04 ioannisj

Quick update on this — I tested it on my device and didn’t notice any major frame drops with or without session replay enabled (though this could vary between high and low-end devices). That said, I did spot some medium hitches in Instruments during screenshot capture, so I’m digging into the snapshot rendering pipeline to see where we can improve performance.

There’s an alternative approach using layer rendering, which should be faster. However, since Google Maps uses a custom rendering layer, it ends up appearing gray in the recordings — so it’s a bit of a trade-off, and I'm guessing this change will have a broader impact on users.

I’ll keep experimenting and continue the quest — will keep you posted! 🙏

ioannisj avatar Apr 30 '25 05:04 ioannisj

@ioannisj I am also having a similar issue where every second (when a snapshot is taken) it takes a ton of processor and makes our app stutter, most noticeable during scrolling. I believe this is from the same root cause. Our app is a SwiftUI based app that is using session replay. I'll attach a stack trace which hopefully helps

Image

finder39 avatar May 02 '25 19:05 finder39

@finder39 thanx for the trace. What device was this running on?

ioannisj avatar May 03 '25 07:05 ioannisj

@ioannisj this is on an iPhone 16 Pro running 18.4.1

finder39 avatar May 03 '25 08:05 finder39

@finder39 and I assume on latest version? I'll push some exploratory changes on Monday probably, would you be okay guys if I ping you then so you can test them out on the same project?

ioannisj avatar May 03 '25 10:05 ioannisj

@ioannisj we are running the latest PostHog version, yes. I'd be happy to test out a version if you sent it off to me.

finder39 avatar May 03 '25 19:05 finder39

Hey all, I pushed some changes on investigate/session-replay-perf branch. When you have a moment, could you please:

  • Point your dependency to that branch
  • Test whether the performance issues you were experiencing are improved
  • Check if the session replay quality meets expectations
    • it's now scaled to 50% size, so lower quality
    • Note: Masking will be misaligned since I didn't account for that - you can turn off masking for testing

Just want to get a feel if I'm heading in the right direction with these changes. In local profiling, with a very low throttleDelay, I do see some performance gains.

Thank you in advance for helping with this!

ioannisj avatar May 05 '25 09:05 ioannisj

@ioannisj that did seem to help. This test was on an iPhone 12 Pro running 18.3.1, so on older hardware as well, but different OS version too. I can test back on the original hardware/OS if you'd like.

A couple things I noticed:

  1. It seems to be doing generation of the screenshot off the main thread now, which is good. Not sure if this is an actual change or if I was looking wrong before.
  2. It seems to take less resources and be less stuttery

Options used:

    config.captureApplicationLifecycleEvents = true
    
    config.sessionReplay = true
    config.sessionReplayConfig.screenshotMode = true
    
    config.sessionReplayConfig.throttleDelay = 1.0
    
    config.sessionReplayConfig.captureNetworkTelemetry = true
    
    config.sessionReplayConfig.maskAllTextInputs = false
    config.sessionReplayConfig.maskAllImages = false
    config.sessionReplayConfig.maskAllSandboxedViews = false

Image

finder39 avatar May 05 '25 18:05 finder39

I can test back on the original hardware/OS if you'd like.

That would be helpful, yes 🙏

It seems to be doing generation of the screenshot off the main thread now, which is good. Not sure if this is an actual change or if I was looking wrong before.

That was not the intend actually. I'm pretty sure if that's the case main thread checker would complain. I'll check again to verify. I also don't see toImage() call in stack trace. If that's the case, however, and it doesn't generate any side effects, I'll take it

It seems to take less resources and be less stuttery

Capturing at 50% scale would explain the smaller memory footprint. Did you check the final session replay in terms of final quality? Does it meet expectations and would this quality work for you?

ioannisj avatar May 06 '25 03:05 ioannisj

@ioannisj thanks! I still see some glitches (iPhone 14), but they are much less critic than it was. I will be monitoring it next days, will let you know how it behave on more powerful devices.

katcinskiy avatar May 06 '25 17:05 katcinskiy

Hey everyone,

I’ve just pushed a couple of commits to investigate/session-replay-perf with an experimental config option: config.sessionReplayConfig.enableBackgroundSnapshotCapture = true

This flag enables snapshotting on a background thread instead of the main thread. I'm pretty sure this will eliminate any glitches you are seeing since main thread will be offloaded. That said, I’m mostly interested in any side effects you notice when this is enabled.

Heads up: Enabling this will trigger Main Thread Checker warnings and may cause a short UI freeze at startup, due to the checker itself though. You may want to disable it during testing.

Please note that this is purely exploratory for now — no promises it’ll make it into a release. But I’d love your feedback if you get a chance to try it out in your app. Let me know if anything breaks or feels odd.

Thanks for helping test this out! 🙏

ioannisj avatar May 14 '25 08:05 ioannisj

@ioannisj works like a charm! No glitches at all, thank you very much!

katcinskiy avatar May 15 '25 18:05 katcinskiy

@ioannisj apologies on the delay! I didn't test the other one on my original device, but I've tested the latest branch. My findings line up with @katcinskiy where there are no glitches with this version. This is great!

I assume this isn't production ready so won't roll the app out with this, but appreciate you looking into and working on this!

finder39 avatar May 15 '25 20:05 finder39

@finder39 @katcinskiy Yeah, this is by no means production ready. Since UIKit APIs aren’t thread-safe, capturing snapshots off the main thread is technically risky. That’s why I’m mostly interested in understanding any potential side effects beyond just performance gains. Please keep an eye on the quality of the session recordings and any visual artifacts, crashes, or other odd behavior. If you see anything that is off, do let me know - Your feedback here is super valuable!

ioannisj avatar May 16 '25 09:05 ioannisj

@ioannisj I currently am back on the main branch with screenshots disabled so we don't get the jitter. I know you mentioned its not production ready, so don't plan to do any releases to users with this branch unless you state otherwise here :)

finder39 avatar May 16 '25 17:05 finder39

I have the exact same issue with my SwiftUI-based app. I profiled it, and there is a micro-hang every second at the exact moment the screenshot is being taken. The glitch/freeze is especially visible when the user scrolls or when the app is doing something computationally expensive.

@ioannisj Is there any update regarding the background capturing? Or any advice on how to improve the situation?

theoks avatar May 27 '25 05:05 theoks

@theoks Hey Theo — I’ve been discussing this with the team to figure out how we can prioritize it. I expect to start working on it fairly soon - I'll keep you all updated here. In the meantime, the only workaround I can suggest is increasing config.sessionReplayConfig.throttleDelay - It won't eliminate the glitching, but it should reduce its frequency.

ioannisj avatar May 27 '25 06:05 ioannisj

I ran into this issue with my react native app, and it drove me crazy tweaking the scroll view and other areas of my app, not realizing it was the sessionReplay from PostHog causing the issue. I'm forced to disable mobile replay for now as the issue is super painful especially on older devices.

Would love a solution

zacyungblut avatar Jun 24 '25 16:06 zacyungblut

@zacyungblut we also had to disable it completely unfortunately. We even got some negative reviews because of the glitches. We'd really love to try a more performant solution.

theoks avatar Jun 24 '25 17:06 theoks

Hey everyone, sorry to hear this is becoming a problem for you guys - I'll work on a quick fix I spotted tomorrow which I hope will help a bit. I'll be OOO next week, though, so I won't be able to work on background session recordings (which seem to help a lot with glitching) until after I'm back

ioannisj avatar Jun 24 '25 19:06 ioannisj

Possible fix that can help with this here - pending review from the team. If you’re able to test it directly from that PR in your apps before we merge, that would be super helpful as well

ioannisj avatar Jun 25 '25 10:06 ioannisj

@ioannisj it is an improvement for sure, but still, even in low-speed scrolling situations there is a very visible glitching that is perceived like a performance issue to the end user.

theoks avatar Jul 04 '25 18:07 theoks

@theoks is this a native app? SwiftUI? On which device are you testing?

ioannisj avatar Jul 07 '25 09:07 ioannisj

@theoks is this a native app? SwiftUI? On which device are you testing?

@ioannisj Native, SwiftUI. I am testing on an iPhone 14 Pro Max.

theoks avatar Jul 07 '25 11:07 theoks

Hello @ioannisj, I am still experiencing freezes on my iPhone 15 Pro Max. I am using SwiftUI and have a ScrollView that contains images. When I scroll, it makes snapshots and it hangs during this process. If I disable the Session Replay feature, the app works correctly without any hangs. SDK version: 3.31.0 iOS versions: 17, 18, and 26

Image

Image

Kolisnyk9 avatar Sep 02 '25 13:09 Kolisnyk9

Hey @Kolisnyk9 🫠 sorry to hear that. I'll have another crack at this tomorrow with a new approach and I'll come back to you soon!

ioannisj avatar Sep 02 '25 14:09 ioannisj

Just a FYI -> @ioannisj is playing with a possible custom renderer improvement, branch here. So far, it hasn't helped much, but there might be some other possible optimizations. He's currently on paternity leave, so we will hear back once he's back in about 2-3 weeks.

marandaneto avatar Sep 08 '25 08:09 marandaneto