Closed Bug 1808223 Opened 2 years ago Closed 8 months ago

cmd-tab back to Firefox window on macOS is slow

Categories

(Core :: Widget: Cocoa, defect)

Firefox 108
defect

Tracking

()

VERIFIED FIXED
121 Branch
Performance Impact low
Tracking Status
firefox121 --- verified

People

(Reporter: twatson52, Assigned: spohl)

References

Details

(Keywords: perf:responsiveness)

Attachments

(1 file)

User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:108.0) Gecko/20100101 Firefox/108.0

Steps to reproduce:

  1. Use Firefox normally for several days without closing it
  2. Use system cmd-tab shortcut to switch to another application
  3. Use system cmd-tab shortcut to switch back to Firefox
  4. Observe significant (several hundred millisecond, increases with amount of time Firefox has been open) delay for Firefox's window to come back on top
  5. Close and reopen Firefox
  6. Observe that cmd-tabbing back to Firefox is now instant

Actual results:

Performance profile for 5 cmd-tab sequences: https://share.firefox.dev/3GuMXRF

Expected results:

This should be instant all the time.

Can confirm, encountering this too.

It looks like we're accumulating "key equivalents" in the menu bar that get removed when the menu bar is painted. Stephen, can you take a look?

Status: UNCONFIRMED → NEW
Component: Performance → Widget: Cocoa
Ever confirmed: true
Flags: needinfo?(spohl.mozilla.bugs)
Performance Impact: --- → ?
Duplicate of this bug: 1810956

This is making Firefox completely unusable for me. Is a fix for this on the roadmap?

Duplicate of this bug: 1820916

Same issue with Firefox 111.0.1 (64-bit), on a M1 Max Macbook Pro with MacOS 13.0.

Anyone who can reproduce this, could you test this build and let us know if you see any improvements?

https://firefox-ci-tc.services.mozilla.com/api/queue/v1/task/ASCL5TZqQuyKISU2p0F9dg/runs/0/artifacts/public/build/target.dmg

Flags: needinfo?(twatson52)
Flags: needinfo?(nitanovidiu)

Sure, it might take several days to make evident though.

Flags: needinfo?(twatson52)

Unfortunately this has not fixed the issue. I don't think there's any improvement. Here is another profile if that is useful: https://share.firefox.dev/3GjeHsS . The browser has been open and in regular use for a couple days at least.

Thanks for letting us know. I'll be taking another look. Leaving n-i set.

Duplicate of this bug: 1828289

A quick way to reproduce this is to hold CMD+tilde (or whatever you have set as the shortcut to switch between windows of the same application). It starts by rapidly switching between firefox windows and slows down noticeably after a minute or two, getting slower and slower.

(In reply to nejc from comment #13)

A quick way to reproduce this is to hold CMD+tilde (or whatever you have set as the shortcut to switch between windows of the same application). It starts by rapidly switching between firefox windows and slows down noticeably after a minute or two, getting slower and slower.

Thank you! I'm finally able to reproduce this. Looking into it.

Duplicate of this bug: 1761447

Hi, I've been encountering this issue more and more lately as well.

I can see that the cause of the the problem is pretty much determined, but here's another performance profile I captured if it can help in any way: https://share.firefox.dev/3HXTR3o
There are 2 hangs in the profile, first one is when I'm switching from Firefox to another window, and the second one is when I'm switching back to Firefox which is the noticable slowness on my part.

Any plans to address this? It's still very annoying to have to fully quit and reopen Firefox almost daily.

Yes, I need to finish up some other work first and will return to this bug as my next priority.

I am also observing this behaviour on MacOS, even with MemoryPressure in "green" (MBP M1 Max, 64GB, 3x external displays).
Profile pre-fireforx-restart: https://share.firefox.dev/44HIuVD (profile indicates 1300 - 1400ms Jank delay)
Profile post-firefox-restart: https://share.firefox.dev/3Ps6dF4 (switching is instant and pleasant)

Hopefully this helps your team address it 🙌

Note: MacOS reported 25GB less memory used when I quite Firefox, and 5GB of that got re-consumed again after restart, but it's green either way and swap file is barely touched (and not for Firefox anyways, as far as I can tell)

P.S. Lmk if I included anything sensitive in the profile files so I could purhe cache or whatnot, but I only ticket URLs/Paths and Extentions as that felt relevant.

Duplicate of this bug: 1850973
Duplicate of this bug: 1849888

I did some poking around, and it looks like the issue here is that new "Start Dictation" and "Emoji & Symbols" items are added to the Edit menu every time a window is focused, when setting the application's mainMenu. This causes the number of items held by the key equivalent uniquer used by [NSApp.mainMenu] to grow without bound, leading to the [NSApp.mainMenu = mNativeMenu;] line taking a long time to delete all the old menu items.

I was able to work around this on my build with a very ugly hack (see the below code), but I'm hoping someone who knows objective-c or Cocoa can provide a more idiomatic fix. Or, if appropriate, report a bug to Apple.

Footnote 1: Ugly work around

I added the following function to widget/cocoa/nsMenuBarX.mm:

static bool removeEmojiAndStartDictationItems(NSMenu* menu) {
  SEL startDictation = @selector(startDictation:);
  SEL emoji = @selector(orderFrontCharacterPalette:);

  NSMutableArray* toRemove = [[NSMutableArray alloc] init];

  for (NSInteger i = 0; i < menu.numberOfItems; ++i) {
    NSMenuItem* item = [menu itemAtIndex:i];

    if ((item.action == startDictation) || (item.action == emoji)) {
      [toRemove addObject:@(i)];
    }

    if (item.hasSubmenu &&
      removeEmojiAndStartDictationItems(item.submenu)) {
      return true;
    }
  }

  for (NSNumber* at in [toRemove reverseObjectEnumerator]) {
    [menu removeItemAtIndex:at.integerValue];
  }

  if (toRemove.count >= 2) {
    return true;
  }
  
  return false;
}

then called it in nsMenuBarX::Paint():

removeEmojiAndStartDictationItems(mNativeMenu);
NSApp.mainMenu = mNativeMenu;

Footnote 2: Viewing the uniquer item list length

In nsMenuBarX::Paint(), add the following code:

id uniquer = [NSApp.mainMenu _getKeyEquivalentUniquerCreatingIfNecessary:true];
id items = [uniquer items];
unsigned long long count = [items count];

Thank you for looking into this and it confirms our suspicion that the menu items were growing without bounds. This bug is next on my list of priorities. I'd like to fix this by switching from a "one main menu per window"-model to a "one main menu per app"-model, which would avoid this problem and presumably be better performance-wise than constantly deleting menu items.

Flags: needinfo?(nitanovidiu)
Blocks: 1765391
Assignee: nobody → spohl.mozilla.bugs
Status: NEW → ASSIGNED

Switching to one menu bar would suffer from a need to keep menu items synchronized for each window. While not impossible, this would be worse performance-wise than removing the problematic menu items as suggested by David in comment 22.

Flags: needinfo?(spohl.mozilla.bugs)
Pushed by spohl@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/4432ccd2193c
Work around a bug in macOS that causes menu items to be added every time a user switches between windows, ultimately causing significant slowdowns when switching between windows. Based on a patch by David Levy. r=mstange

Backed out as requested by developer

Backout link

Flags: needinfo?(spohl.mozilla.bugs)

After landing the patch, I discovered that the issue here actually has to do with hidden menu objects that macOS adds to the NSApp.mainMenu, rather than the visible menu items. These extra menu items are presumably to accommodate alternative key shortcuts. Here is the output when printing the contents of the "Edit" menu after switching between menus several times:

<GeckoNSMenu: 0x1573b4800>
	Title: Edit
	Supermenu: 0x1574d6180 (MainMenuBar), autoenable: NO
	Previous menu: 0x0 (None)
	Next menu: 0x0 (None)
	Items:     (
        "<NSMenuItem: 0x136553f90 Undo, ke='Command-Z'>",
        "<NSMenuItem: 0x136568170 Redo, ke='Shift-Command-Z'>",
        "<NSMenuItem: 0x136568b10 >",
        "<NSMenuItem: 0x136568250 Cut, ke='Command-X'>",
        "<NSMenuItem: 0x136568560 Copy, ke='Command-C'>",
        "<NSMenuItem: 0x1365681e0 Paste, ke='Command-V'>",
        "<NSMenuItem: 0x1365685d0 Delete, ke='\U2326'>",
        "<NSMenuItem: 0x1365682c0 >",
        "<NSMenuItem: 0x136568330 Select All, ke='Command-A'>",
        "<NSMenuItem: 0x136568640 >",
        "<NSMenuItem: 0x136568800 Find in Page\U2026, ke='Command-F'>",
        "<NSMenuItem: 0x136568fe0 Find Again, ke='Command-G'>",
        "<NSMenuItem: 0x13645a550 >",
        "<NSMenuItem: 0x136479130 AutoFill, submenu: 0x15220a740 ()>",
        "<NSMenuItem: 0x13647a0f0 Start Dictation\U2026>",
        "<NSMenuItem: 0x10e5c5520 Start Dictation\U2026, hidden>",
        "<NSMenuItem: 0x10ce9c410 Start Dictation\U2026, hidden>",
        "<NSMenuItem: 0x10cef8d40 Start Dictation\U2026, hidden>",
        "<NSMenuItem: 0x106f7e9b0 Start Dictation\U2026, hidden>",
        "<NSMenuItem: 0x106f7d830 Start Dictation\U2026, hidden>",
        "<NSMenuItem: 0x12cd67660 Start Dictation\U2026, hidden>",
        "<NSMenuItem: 0x136478e20 Start Dictation\U2026, hidden>",
        "<NSMenuItem: 0x1365f3890 Start Dictation\U2026, hidden>",
        "<NSMenuItem: 0x13647aa20 Start Dictation\U2026, hidden>",
        "<NSMenuItem: 0x136479d70 Emoji & Symbols, ke='Function-E'>",
        "<NSMenuItem: 0x10eacb820 Emoji & Symbols, ke='Control-Command-Space bar', hidden>",
        "<NSMenuItem: 0x10eacada0 Emoji & Symbols, ke='Function-E', hidden>",
        "<NSMenuItem: 0x10ce9c560 Emoji & Symbols, ke='Control-Command-Space bar', hidden>",
        "<NSMenuItem: 0x10e5c43a0 Emoji & Symbols, ke='Function-E', hidden>",
        "<NSMenuItem: 0x10cef81e0 Emoji & Symbols, ke='Control-Command-Space bar', hidden>",
        "<NSMenuItem: 0x10cef9440 Emoji & Symbols, ke='Function-E', hidden>",
        "<NSMenuItem: 0x106f7ec50 Emoji & Symbols, ke='Control-Command-Space bar', hidden>",
        "<NSMenuItem: 0x106f7efd0 Emoji & Symbols, ke='Function-E', hidden>",
        "<NSMenuItem: 0x106f7dbb0 Emoji & Symbols, ke='Control-Command-Space bar', hidden>",
        "<NSMenuItem: 0x106f7d8a0 Emoji & Symbols, ke='Function-E', hidden>",
        "<NSMenuItem: 0x12cd91750 Emoji & Symbols, ke='Control-Command-Space bar', hidden>",
        "<NSMenuItem: 0x12cd92550 Emoji & Symbols, ke='Function-E', hidden>",
        "<NSMenuItem: 0x136478090 Emoji & Symbols, ke='Control-Command-Space bar', hidden>",
        "<NSMenuItem: 0x136478950 Emoji & Symbols, ke='Function-E', hidden>",
        "<NSMenuItem: 0x1365f3970 Emoji & Symbols, ke='Control-Command-Space bar', hidden>",
        "<NSMenuItem: 0x1365f3ac0 Emoji & Symbols, ke='Function-E', hidden>",
        "<NSMenuItem: 0x1364b8bf0 Emoji & Symbols, ke='Control-Command-Space bar', hidden>",
        "<NSMenuItem: 0x1364d57c0 Emoji & Symbols, ke='Function-E', hidden>"
    )

Only removing these hidden menu items seems like a safer, more future-proof fix.

Flags: needinfo?(spohl.mozilla.bugs)
Attachment #9363234 - Attachment description: Bug 1808223: Work around a bug in macOS that causes menu items to be added every time a user switches between windows, ultimately causing significant slowdowns when switching between windows. Based on a patch by David Levy. r=mstange → Bug 1808223: Work around a bug in macOS that causes hidden menu items to be added every time a user switches between windows, ultimately causing significant slowdowns when switching between windows. Based on a patch by David Levy. r=mstange

The Performance Impact Calculator has determined this bug's performance impact to be low. If you'd like to request re-triage, you can reset the Performance Impact flag to "?" or needinfo the triage sheriff.

Platforms: macOS
Impact on browser: Causes noticeable jank
Configuration: Rare
[x] Multiple reporters

Performance Impact: ? → low
Pushed by spohl@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/ceabf6cc9da3
Work around a bug in macOS that causes hidden menu items to be added every time a user switches between windows, ultimately causing significant slowdowns when switching between windows. Based on a patch by David Levy. r=mstange
Status: ASSIGNED → RESOLVED
Closed: 8 months ago
Resolution: --- → FIXED
Target Milestone: --- → 121 Branch
No longer blocks: 1765391
Flags: qe-verify+

I haven't managed yet to reproduce this issue based on the STR from Comment 0.
Thomas, could you please confirm if the issue no longer reproduces for you in the latest Nightly 122.0a1 and Firefox 121.0b8? Thanks

Flags: needinfo?(twatson52)

(In reply to Ina Popescu, Desktop QA from comment #32)

I haven't managed yet to reproduce this issue based on the STR from Comment 0.
Thomas, could you please confirm if the issue no longer reproduces for you in the latest Nightly 122.0a1 and Firefox 121.0b8? Thanks

An easy way to reproduce this issue is by following the steps from comment 13:

(In reply to nejc from comment #13)

A quick way to reproduce this is to hold CMD+tilde (or whatever you have set as the shortcut to switch between windows of the same application). It starts by rapidly switching between firefox windows and slows down noticeably after a minute or two, getting slower and slower.

Flags: needinfo?(twatson52)

(In reply to Stephen A Pohl [:spohl] from comment #33)

(In reply to Ina Popescu, Desktop QA from comment #32)

I haven't managed yet to reproduce this issue based on the STR from Comment 0.
Thomas, could you please confirm if the issue no longer reproduces for you in the latest Nightly 122.0a1 and Firefox 121.0b8? Thanks

An easy way to reproduce this issue is by following the steps from comment 13:

(In reply to nejc from comment #13)

A quick way to reproduce this is to hold CMD+tilde (or whatever you have set as the shortcut to switch between windows of the same application). It starts by rapidly switching between firefox windows and slows down noticeably after a minute or two, getting slower and slower.

I'm still not able to reproduce this issue in Firefox 108.0 on macOS 13 when following both STR and suggestions from Comment 0 and Comment 13.
There is no noticeable slowness when switching between windows using CMD+TAB. I'm still able to open afterwards new tab or new window in Firefox no matter for how long the browser was opened. Is there anything else I could try here in order to reproduce this?

(In reply to Ina Popescu, Desktop QA from comment #34)

I'm still not able to reproduce this issue in Firefox 108.0 on macOS 13 when following both STR and suggestions from Comment 0 and Comment 13.
There is no noticeable slowness when switching between windows using CMD+TAB. I'm still able to open afterwards new tab or new window in Firefox no matter for how long the browser was opened. Is there anything else I could try here in order to reproduce this?

Do you have about 10 windows open and are you holding Cmd+~ pressed for about 3 minutes (note, you need to press ~, not TAB as you mentioned in your comment)? You should be switching between Firefox windows, rapidly at first and after about 3 minutes you should start noticing a significant slowdown. You will still be able to open new tabs and windows when the slowdown occurs. The bug here is about the significant slowdown that people experience when switching between windows.

Comment 0 refers to the slowdown occurring by pressing Cmd+Tab. However, this would take significantly longer to reproduce. So a quicker way to reproduce it is to use Cmd+~ and switching between Firefox windows. The underlying bug that was fixed here is the same.

Flags: needinfo?(epopescu)

spohl, thanks for the extra details provided.
I've reproduced this issue using Firefox 108.0 on macOS 13 following the STR from Comment 35.
Verified as fixed in the latest Nightly 122.0a1 and Firefox 121 versions under same configuration where the issue no longer persists.

Status: RESOLVED → VERIFIED
Flags: qe-verify+
Flags: needinfo?(epopescu)
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: