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)
Tracking
()
| Performance Impact | low |
People
(Reporter: 5silentrain, Unassigned, NeedInfo)
References
Details
(Keywords: perf)
Attachments
(1 file)
|
167.89 KB,
image/png
|
Details |
| Reporter | ||
Updated•9 years ago
|
Updated•9 years ago
|
Comment 1•9 years ago
|
||
| Reporter | ||
Comment 2•9 years ago
|
||
| Reporter | ||
Comment 3•9 years ago
|
||
Comment 4•9 years ago
|
||
| Reporter | ||
Comment 5•9 years ago
|
||
Comment 6•9 years ago
|
||
| Reporter | ||
Comment 7•9 years ago
|
||
| Reporter | ||
Comment 8•9 years ago
|
||
| Reporter | ||
Comment 9•9 years ago
|
||
Comment 10•9 years ago
|
||
| Reporter | ||
Comment 11•9 years ago
|
||
| Reporter | ||
Comment 12•7 years ago
|
||
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.
| Reporter | ||
Comment 13•5 years ago
|
||
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 👍
Updated•3 years ago
|
Comment 14•7 months ago
|
||
It's crazy that this hasn't been fixed after 9 years.
Comment 15•7 months ago
|
||
Zekov, assuming you have seen this issue, can you help out by collecting a profile where you reproduce it? Here are the steps:
- 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.
- 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".
- Press Ctrl+Shift+1 to start the profiler.
- 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.
- Press Ctrl+Shift+2 to stop the profile. A new tab will open with profiler results.
- The browser is still "symbolicating" the profile but you can just upload it immediately with "Upload local profile" in the upper-right corner.
- 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.
Comment 17•7 months ago
|
||
(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:
- 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.
- 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".
- Press Ctrl+Shift+1 to start the profiler.
- 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.
- Press Ctrl+Shift+2 to stop the profile. A new tab will open with profiler results.
- The browser is still "symbolicating" the profile but you can just upload it immediately with "Upload local profile" in the upper-right corner.
- 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 oftennsAppShell::EventWindowProcis 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.
Comment 18•6 months ago
|
||
(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:
- 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.
- 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".
- Press Ctrl+Shift+1 to start the profiler.
- 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.
- Press Ctrl+Shift+2 to stop the profile. A new tab will open with profiler results.
- The browser is still "symbolicating" the profile but you can just upload it immediately with "Upload local profile" in the upper-right corner.
- 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.
Comment 19•6 months ago
|
||
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?
Comment 20•6 months ago
|
||
(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
nsNativeDragTargetcould 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.
Comment 21•6 months ago
|
||
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)?
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.
Comment 23•6 months ago
|
||
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.
Comment 24•6 months ago
|
||
(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 --
requestAnimationFrameis 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) ?
Comment 25•6 months ago
|
||
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).
Comment 26•6 months ago
|
||
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.
Description
•