Open Bug 1306925 Opened 9 years ago Updated 6 months ago

If you set a high Polling Rate USB port of the mouse (1000 Hz), there will be noticeable performance issues while moving tabs

Categories

(Core :: Widget: Win32, defect)

49 Branch
x86_64
Windows 7
defect

Tracking

()

Performance Impact low

People

(Reporter: 5silentrain, Unassigned, NeedInfo)

References

Details

(Keywords: perf)

Attachments

(1 file)

Attached image Screenshot 1.png
User Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:49.0) Gecko/20100101 Firefox/49.0 Build ID: 20160922113459 Steps to reproduce: Use a gaming mouse with a polling rate of the USB port equal to 1000 Hz. Actual results: Moving tabs on the tab bar occurs with strong performance issues. Expected results: Moving tabs should be as smooth as in Chrome. At 125 Hz the smoothness is dramatically improved!
Component: Untriaged → Tabbed Browser
OS: Unspecified → Windows 7
Hardware: Unspecified → x86_64
Component: Tabbed Browser → Untriaged
Product: Firefox → Core
Based on the fact that I don't have a mouse like this for testing, I can't test it. I will move it to widget: Win32 since it seems to be specific to windows hardware support. Can you please try something: Please download the Firefox Nightly from here: https://nightly.mozilla.org/ and retest the problem. If you still have the issue please create a new profile, you have the steps here:https://support.mozilla.org/en-US/kb/profile-manager-create-and-remove-firefox-profiles?redirectlocale=en-US&redirectslug=Managing-profiles#w_starting-the-profile-manager Please test if the issue can be reproduced in the safe mode of Firefox: https://support.mozilla.org/en-US/kb/troubleshoot-firefox-issues-using-safe-mode
Component: Untriaged → Widget: Win32
Flags: needinfo?(5silentrain)
The problem exists in Safe Mode too. The same problem occurs in a new tab when you try to move the thumbnails. Just try ANY mouse with a Polling Rate of 1000 Hz in your browser. That's all. It's simple ;)
Really none of the Mozilla Corporation employees do not have a mouse with a Polling Rate of 1000 Hz?! O__O Seriously???
Hi 5silentrain, When I said that I don't have that kind of mouse I was referring to myself. That is the reason way I move this issue to a component without testing it.
(In reply to ovidiu boca[:Ovidiu] from comment #4) > Hi 5silentrain, > > When I said that I don't have that kind of mouse I was referring to myself. > That is the reason way I move this issue to a component without testing it. Except you no one else can verify this bug??? o_O
I am not the only one, let see what the developers from this component can tell about this issue. Thanks
OK :)
Someone from Mozilla employees confirm this bug which is not fixed for many years?
The bug is present in Firefox Nightly and all versions of Firefox!!!
User Agent Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:52.0) Gecko/20100101 Firefox/52.0 Build ID 20161018030211 Hi 5silentrain, I have tested your issue with a mouse capable of 1000 Hz poll rate and I have found the following on the latest Nightly: With 4 tabs opened and the mouse set at 125 Hz, while moving tabs CPU usage is at about 12-15%. With 4 tabs opened and the mouse set at 1000 Hz, while moving tabs CPU usage is at about 20-25%. With e10s enabled and disabled I haven't observed any performance issues while doing this. However, I opened a lot of tabs in order to raise the CPU usage (around 30 with 10 YouTube videos). This brought the CPU usage to 70% after it stabilized. Moving Tabs and the New Tab page tiles does show some lag and CPU usage further increases to 90%. This is both with 1000Hz and 125Hz. Seems to me like this is a more general issue related to CPU and RAM load and not something strictly related to the mouse polling rate. Indeed 1000Hz rate does help to see this better but it does almost the same with 125Hz in the same conditions.
Status: UNCONFIRMED → NEW
Ever confirmed: true
It would be great if the smooth of moving tabs on the tab bar was the same like in Chrome and Opera =(

After buying a new computer (Intel NUC Hades Canyon (HVK)), the smoothness of moving tabs has increased dramatically 👍 Now I have no complaints about the smoothness of moving tabs.

Flags: needinfo?(5silentrain)
Keywords: perf

The bug is still present even in the most recent dev version (89.0b4) 😢 Please someone fix this behavior by making the tabs move smoothly 🙏

P. S. Everything is smooth in Chrome 👍

Severity: normal → S3

It's crazy that this hasn't been fixed after 9 years.

Zekov, assuming you have seen this issue, can you help out by collecting a profile where you reproduce it? Here are the steps:

  1. Prepare Firefox to reproduce the bug by doing whatever you need to (if there are previously unmentioned steps, add them here). Make sure you avoid tabs with private information, like email.
  2. Enable some useful logging. To do this, enter about:logging in the URL bar, and, under "New log modules", enter: WidgetDragService:5 (capitalization is important) and click "Set Log Modules".
  3. Press Ctrl+Shift+1 to start the profiler.
  4. Drag a tab. Try to make it clear that the performance is bad. Do this a few times but space them out with a second or two so it's clear when you start and when you stop.
  5. Press Ctrl+Shift+2 to stop the profile. A new tab will open with profiler results.
  6. The browser is still "symbolicating" the profile but you can just upload it immediately with "Upload local profile" in the upper-right corner.
  7. The upload will give you a share.firefox.dev link that you can post here or email to me if you prefer.

Technical notes: We may just be getting spammed by the device driver with redundant events that we aren't throttling. If so, there are a lot of potential fixes but the simplest would probably be to just always throttle drag events to 125Hz. We probably don't see this with events in pages because they are already throttled by IPC.

Flags: needinfo?(xdexde10)
Duplicate of this bug: 1914114

(In reply to David Parks [:handyman] from comment #15)

Zekov, assuming you have seen this issue, can you help out by collecting a profile where you reproduce it? Here are the steps:

  1. Prepare Firefox to reproduce the bug by doing whatever you need to (if there are previously unmentioned steps, add them here). Make sure you avoid tabs with private information, like email.
  2. Enable some useful logging. To do this, enter about:logging in the URL bar, and, under "New log modules", enter: WidgetDragService:5 (capitalization is important) and click "Set Log Modules".
  3. Press Ctrl+Shift+1 to start the profiler.
  4. Drag a tab. Try to make it clear that the performance is bad. Do this a few times but space them out with a second or two so it's clear when you start and when you stop.
  5. Press Ctrl+Shift+2 to stop the profile. A new tab will open with profiler results.
  6. The browser is still "symbolicating" the profile but you can just upload it immediately with "Upload local profile" in the upper-right corner.
  7. The upload will give you a share.firefox.dev link that you can post here or email to me if you prefer.

Technical notes: We may just be getting spammed by the device driver with redundant events that we aren't throttling. If so, there are a lot of potential fixes but the simplest would probably be to just always throttle drag events to 125Hz. We probably don't see this with events in pages because they are already throttled by IPC.

There was a profile in the dupe, but shared as a file rather than the upload interface, and so it doesn't appear to be available anymore. Markus earlier said:

(In reply to Markus Stange [:mstange] from bug 1914114 comment #13)

The native event loop is being spun inside MS's code, but our Gecko event loop servicing happens from the event loop's user callback, which we install: nsAppShell::EventWindowProc. Someone would need to reproduce this issue and check how often nsAppShell::EventWindowProc is called - either it's called too rarely by the native event loop, or it is called often enough and we're just choosing to not process Gecko events some of the time.

I don't suppose that's enough to go on here? Off-hand it sounds to me like the throttling you suggest would help.

Performance Impact: --- → low
Flags: needinfo?(davidp99)

(In reply to David Parks [:handyman] from comment #15)

Zekov, assuming you have seen this issue, can you help out by collecting a profile where you reproduce it? Here are the steps:

  1. Prepare Firefox to reproduce the bug by doing whatever you need to (if there are previously unmentioned steps, add them here). Make sure you avoid tabs with private information, like email.
  2. Enable some useful logging. To do this, enter about:logging in the URL bar, and, under "New log modules", enter: WidgetDragService:5 (capitalization is important) and click "Set Log Modules".
  3. Press Ctrl+Shift+1 to start the profiler.
  4. Drag a tab. Try to make it clear that the performance is bad. Do this a few times but space them out with a second or two so it's clear when you start and when you stop.
  5. Press Ctrl+Shift+2 to stop the profile. A new tab will open with profiler results.
  6. The browser is still "symbolicating" the profile but you can just upload it immediately with "Upload local profile" in the upper-right corner.
  7. The upload will give you a share.firefox.dev link that you can post here or email to me if you prefer.

Technical notes: We may just be getting spammed by the device driver with redundant events that we aren't throttling. If so, there are a lot of potential fixes but the simplest would probably be to just always throttle drag events to 125Hz. We probably don't see this with events in pages because they are already throttled by IPC.

https://share.firefox.dev/4rFjryh

Flags: needinfo?(xdexde10)

Markus had the right idea but there was still some question as to whether it was starving the AppShell or spamming it, but Zekov just answered that definitively (thanks Zekov!). Here's a snippet of their log:

 1.281s            LogMessages  (I/WidgetDragService) [13dfd40db40] nsNativeDragTarget::DispatchDragDropEvent | Dispatching dragenter event at client pos (527, 6)
 1.281s            LogMessages  (I/WidgetDragService) [13dfd40db40] nsNativeDragTarget::DispatchDragDropEvent | Dispatching dragover event at client pos (527, 6)
 1.285s            LogMessages  (I/WidgetDragService) [13dfd40db40] nsNativeDragTarget::DispatchDragDropEvent | Dispatching dragover event at client pos (531, 7)
 1.287s            LogMessages  (I/WidgetDragService) [13dfd40db40] nsNativeDragTarget::DispatchDragDropEvent | Dispatching dragover event at client pos (532, 8)
 1.288s            LogMessages  (I/WidgetDragService) [13dfd40db40] nsNativeDragTarget::DispatchDragDropEvent | Dispatching dragover event at client pos (533, 8)
 1.290s            LogMessages  (I/WidgetDragService) [13dfd40db40] nsNativeDragTarget::DispatchDragDropEvent | Dispatching dragover event at client pos (533, 8)
 1.291s            LogMessages  (I/WidgetDragService) [13dfd40db40] nsNativeDragTarget::DispatchDragDropEvent | Dispatching dragover event at client pos (535, 8)
 1.293s            LogMessages  (I/WidgetDragService) [13dfd40db40] nsNativeDragTarget::DispatchDragDropEvent | Dispatching dragover event at client pos (536, 8)

It goes on like this. At 1000Hz, we could get a dragover message every 0.001s, and we very nearly do. Each one that involves an actual move (and we can see that not all do) requires a reflow of the tab bar. We can certainly ignore messages that come in at a higher rate than every 0.125s. Judging from this log snippet, we would be skipping ~80 reflows for each one we did. That's got to be enough to correct this.

As for how to handle it, I don't think we can tell Windows to slow down. Filtering the events through a timer would be simple enough, but should we do that at the widget level and throttle for the entire browser, or just at the tab-dragging level? Related: earlier I mentioned that we throttle input events to content before (in PBrowser), but I missed that we don't do that for drag events (just mouse events), so whole-browser would potentially be a bigger (but maybe also useful) change. E.g. games could feel different. Do we think we have this dragging performance problem in places other than tab dragging? Gijs, I'm considering a pref that nsNativeDragTarget could use to set the max poll rate (and default to 125), in case folks want to play with the max rate for some reason (like games) but do you think this should instead be simple and just limited to tabs?

Flags: needinfo?(davidp99) → needinfo?(gijskruitbosch+bugs)

(In reply to David Parks [:handyman] from comment #19)

E.g. games could feel different. Do we think we have this dragging performance problem in places other than tab dragging?

I don't know, at a high level. I have never seen performance issues on the web with dragging come by in triage, but then I would also not expect them to be in the components I triage. Some older bugs do appear to exist, e.g. bug 789949 and bug 728189 but it's unclear to me how much they relate to this ticket or to other underlying issues. I used this query, for reference.

It might be worth asking Masayuki or other DOM folks.

Gijs, I'm considering a pref that nsNativeDragTarget could use to set the max poll rate (and default to 125), in case folks want to play with the max rate for some reason (like games) but do you think this should instead be simple and just limited to tabs?

From my pov the pref sounds like a good idea. Not only do we have a way of easily disabling it if it causes issues, it might yield some performance improvements for some folks outside of tab dragging, and there may be future opportunities to lower it further in certain situations (e.g. for energy conservation reasons or similar).

I hope that helps a tiny bit? Bouncing ni in case you want to also ask DOM folks for input.

Flags: needinfo?(gijskruitbosch+bugs) → needinfo?(davidp99)

Good point. Masayuki, do you have an opinion about this? Do you know if we do any rate-limiting of drag events anywhere? We don't do the IPDL compress throttling that we do for mouse events but maybe there is something else that is supposed to kick in here? Are there bugs related to overloading the event queue during drags? Maybe even on other platforms, since a fix could potentially work everywhere (although the one I have in mind is Windows-only)?

Flags: needinfo?(davidp99) → needinfo?(masayuki)

As far as I know, we don't have any special handling for the high-rate DnD inputs. Edgar must know better than me so that let's ask him.

On the other hand, I think we should limit the rate as same as we're doing for mousemove to avoid the content process to be junk. However, about in the parent process, perhaps, we could just stop dispatching dragover if and only if the coordinates are the same as the previous event.

As far as possible, we need to expose the user inputs as-is especially for gaming. So, if the reflow cost is not cheap for mousemove, dragover, pointermove, etc, basically the app (in this context, the DnD handler for the tab) should put the job into the queue and coalesce multiple jobs into one. E.g., IME handler in the content process notifies the content change to IME in the parent process when a vsync event. Thus, I think the DnD handler should use requestAnimationFrame or something to handle the dragover result and stop handling it synchronously in the event listener.

Flags: needinfo?(masayuki) → needinfo?(echen)

I assume the drag messages were never compressed in IPDL because we weren't seeing a need but I agree it makes sense to do. We can also filter out the redundant movements at the widget level, although that wasn't a major factor here. And it sounds right to me that tab dragging would do it's own throttling -- requestAnimationFrame is a good idea.

(In reply to David Parks [:handyman] from comment #23)

I assume the drag messages were never compressed in IPDL because we weren't seeing a need but I agree it makes sense to do. We can also filter out the redundant movements at the widget level, although that wasn't a major factor here. And it sounds right to me that tab dragging would do it's own throttling -- requestAnimationFrame is a good idea.

I'm kind of surprised by this suggestion - wouldn't this mean that the drag would always "lag behind" the cursor a bit, because it would always wait to process any event until the next "frame" / layout/paint refresh cycle (usually 16ms) ?

Also, the return value / whether we call event.preventDefault() and event.stopPropagation() AIUI influences the UI feedback the drag gives the user (in terms of the cursor) - I don't think we have a choice about processing those on the frontend (and have to do it immediately, not on the next rAF).

I don't see how the part of tab dragging animated by Gecko could redraw faster than rAF but maybe window chrome rendering works differently than in the page? Either way, the part animated by Windows (the cursor and attached ghost image) shouldn't be affected. IOW, I don't think it would look any differently than it does now -- we just wouldn't be doing a bunch of reflows that we immediately throw out since we reflow again before we have a chance to update the rendering to reflect them. If anything, I'd think dropping the wasted reflows should make the animation (much) smoother.

I didn't know that preventDefault and stopPropagation had any influence on the drag image. I can't really guess what that could be but it doesn't seem like it should change anything. If that's not intentional then maybe we can fix it but, if it is, then I guess we need a different plan. This is all very DOM-y so it makes more sense for you and @echen to make this call than me. But from the sidelines, @masayuki's suggestions seem to make the most sense.

You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: