New mobile menu panel moving slow and laggy on older devices

AI-generated summary

User Don reported that since the update in PR #23775, the mobile menu panel (user and sidebar) feels slow and laggy on older Android devices like the Huawei P20 Pro, though it runs smoothly on iPhone X — suggesting CPU limitations. The issue appears most noticeable during menu opening/closing, especially after the first load (when animations are absent), and sometimes affects button responsiveness. Gesture-based closing, however, remains smooth. Interestingly, Don found the issue absent in Firefox but present in Chrome and Edge. featheredtoast investigated and concluded the perceived lag isn’t from animations themselves, but from header re-rendering happening too soon after animation starts. They suspect Firefox handles animation end events differently — waiting until painting is complete — while Chrome starts recalculations earlier. To fix this, featheredtoast introduced a small delay using Discourse’s runloop before triggering re-renders, improving perceived smoothness. Don confirmed the fix works well, praising the solution. The fix is implemented in PR #24168.

Hello :waving_hand:

Since the UX: improve touch, swipe, panning performance on mobile menus by featheredtoast · Pull Request #23775 · discourse/discourse · GitHub update the menu panel (user and sidebar) moving feels much slower than before on older mobile Android devices. It maybe because these devices CPU performance is not enough to make it moves smooth.

On my device Huawei P20 Pro.

However I tested it on iPhone X too which is super smooth and fast so I think the CPU will be the problem. Is that any chance to improve performance on older devices?

Thank you :slightly_smiling_face:

6 Likes

Thanks @Don we will have a look!

2 Likes

Hey Don, thanks for the feedback!

I’ll have this tested soon; my suspicion is that older devices may still need the (slightly hacky) perf optimization reducing the number of items in the menu to 20 to feel smooth - Will look into this shortly.

3 Likes

@Don - just further digging in to know what to test for, are you noticing this for opening/closing menus with a tap (on menu + off menu), or swiping (holding and gesturing swipe)?

2 Likes

The menu seems smooth when I firstly opens it. I think because the panel elements not loaded. When I firstly open the spinner loader appears on top. I think this is a good behavior and maybe going to be cool to use always the spinner loader on openings. :thinking:

The openings after this is without animations. The closing is random (sometimes smooth sometimes laggy)

When it opened and I click outside usually the panel menu buttons lagging. But those slide out first :thinking: Maybe this is happens because the whole menu panel is in reverse-row and when it closes the class removes before it fully slide out and change back to row?

Edit: That is not the menu panel buttons (tab) that’s just the icons before notifications. But it’s usually lagg appear on that line.

When I use gesture to close menu it seems smooth.

2 Likes

Update: It seems in Firefox browser the menu moving is smooth. I tested it also on Edge where same as Chrome.

Firefox

From what I can tell, the “lagginess” here is due to headers re-rendering, not the animations themselves.

One thing I did introduce that may give the perception of new-slowness is the slide-out animation (this animation was inadvertently removed when we refactored our new header)

Giving some setTimeout breathing room between animation and the rerender work the widget menus are doing seem to make things go a lot smoother, so it’s not the animation itself that’s slow, so my suspicion is it’s the work going on around rerendering the site headers on open/close.

I’m actually wondering if firefox’s handling of animation end promise is firing after the animation is well and truly painted (I had assumed this to be the case when coding the original change), which might explain why it looks smoother than chrome, whereas chrome allows recalculation work to start after the animation’s calculations are done, but before the animation end is painted.


EDIT: I’m adding a pause using our runloop to add the necessary breathing space before animating, this should make the animation feel much smoother: UX: call discourseLater on menu animations by featheredtoast · Pull Request #24168 · discourse/discourse · GitHub

3 Likes

Whooo thanks so much! Nice catch! :heart_eyes:

2 Likes