New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 600385 link

Starred by 38 users

Issue metadata

Status: Fixed
Owner:
Closed: May 2016
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Windows , Mac
Pri: 3
Type: Bug



Sign in to add a comment

Websocket onmessage lags while left mouse + mousemove

Reported by zushiwar...@gmail.com, Apr 4 2016

Issue description

Chrome Version       : 49.0.2623.87 (Официальная сборка) m (32 бит)
URLs (if applicable) :
Other browsers tested:
  Add OK or FAIL after other browsers where you have tested this issue:
    Firefox: PASS (Version 45.0.1)


What steps will reproduce the problem?
(1) receive data on websocket (packet every 50ms)
(2) press left mouse and move mouse
(3) print pauses between onmessage

What is the expected result?
~50ms pauses

What happens instead?
it lags. up to second in my case 

-----

In webgl game receiving data from server lags when player presses left mouse and move mouse (aiming and shooting, for example). 

Wireshark shows that packets arive in time, but chrome keep them for some time (up to second in my case). 
In my case I have scene on page with about 50-60fps. 

Bug is very critical for real time multiplayer games.

It also appears on mac os


 
Cc: rnimmagadda@chromium.org
Labels: Needs-Feedback
Unable to repro this issue on Windows 7 for Google Chrome Stable Version - 49.0.2623.110 

Screen-recording is attached.

@zushiwarigan: Could you please have a look at the attached video and let us know if this is the correct procedure to repro this issue.

Also, provide us the Game that is lagging along with the screen-recording would help us in triaging it further.

Thank you.
600385.mp4
3.6 MB Download
Components: Blink>WebSockets
Labels: OS-Mac
Great video, but I can't tell if there is a bug there. 
I don't have lags in fps too. Graphics are smooth. 

My problem is that websocket.onmessage doesn't happen, though packets arrived. 
So graphics is smooth but other players are moving with lags. 
I can't show you my game because it's in russian social network and in russian and you have to  go through tutorial to fight and find opponents. So we'll make a simple demo later.

other reports:
https://bugs.chromium.org/p/chromium/issues/detail?id=450258 here comment 32-36
http://stackoverflow.com/questions/36212059/javascript-left-mousedown-mousemove-blocking-other-events-from-firing
In the last link you'll find video and code and much better explanation that i've provided. 

Project Member

Comment 5 by sheriffbot@chromium.org, Apr 6 2016

Labels: -Needs-Feedback Needs-Review
Owner: rnimmagadda@chromium.org
Thank you for providing more feedback. Adding requester "rnimmagadda@chromium.org" for another review and adding "Needs-Review" label for tracking.

For more details visit https://sites.google.com/a/chromium.org/dev/issue-tracking/autotriage - Your friendly Sheriffbot
Labels: -Needs-Review Te-NeedsFurtherTriage
Owner: ----
Unable to reproduce. I have a couple of questions.

1. I don't understand "print pauses between onmessage". Can you explain it?
2. How busy the main thread (i.e. the CPU assigned to the main thread) is?
3.  issue 450258  looks this behavior is caused by the high CPU load on redraw. It is true?

Thanks,
1. Example below. 
2. Near to 100%
3. Yes it happens when drawing and calculations are rather intense. 

Look here:
https://codepen.io/gustos/pen/WwMRBy

open console to make your cpu busy (if it still not busy - add more iterations in string 92 in JS tab)

and make drag move (press and move) in the field with balls. This drag should stop everything. 

So it turns out, this is not problem of websockets, other events are blocked too. 
It happens when fps are lower than 60. 
40-50 fps - ok for a game. even 20-30 can be ok on slow computer. but because of this problem game becomes unplayable with fps lower than 60. 

And it is nearly impossible to make beautiful detailed 3d scene with stable 60fps on any computer. 
And if your fps are too low in my example, change string 92 to less iterations. 
Even on 50 fps you should see the effect. 

Comment 11 by tkent@chromium.org, Apr 11 2016

Components: -Blink>WebSockets Blink>Network>WebSockets
Components: -Blink>Network>WebSockets Blink>DOM
I agree that this is not related to WebSocket.
I'm not sure who is the right owner, but Blink>DOM people may know more than I do.
Have you reproduced it successfuly? 
Need more help or examples?

Comment 15 by tkent@chromium.org, Apr 14 2016

Cc: skyos...@chromium.org
Components: -Blink>DOM Blink>Scheduling Blink>Input
Could you test this with Chrome dev (M51)? I'm wondering if this is related to https://codereview.chromium.org/1834853003.
I've downloaded from here:
https://www.google.com/chrome/browser/desktop/index.html?extra=devchannel&platform=win64

Версия 51.0.2704.7 dev-m (64-bit)

the problem still exists. 

the simplest way to check:
https://codepen.io/gustos/pen/WwMRBy
check if fps<60 (if 60 add iterations in js string 92)
and make a drag on panel with balls. 
with fps 57 i have the problem every time
Hotlist-ImportantForGames 

Comment 19 by ranz...@gmail.com, Apr 17 2016

So I thought I was going crazy, not understanding how left-clicking could cause websocket.onmessage to get held-up, spiking my ping into the 1000s until I let go, but apparently I'm not the only one.

http://caliber.online is suffering from this severely since I jumped to 50.0.2661.75 m (64-bit) today. If you do give caliber a whirl, you can use spacebar to fire instead of left-click and have no impact on the websocket, but if you left-click and try to keep your mouse on a target you'll see the ping meter climb.

No other input is really affected on Caliber, just left-click. Caliber runs on requestanimationframe, which easily reaches 120fps on my system/monitor, so I don't believe fps is related. The websocket.onmessage hanging is just sometimes a bit random and seems to pile up on itself.

zushiwar...'s codepen shows it perfectly: left-click and drag and the websocket grinds to a halt. It also shows the same delaying of the websocket on rolling the mousewheel too.

This is a _major_ issue for websocket performance and I think is instead related to mouse events.

Comment 20 by ranz...@gmail.com, Apr 17 2016

I even tried wrapping my websocket in a webworker:

http://caliber.online/libs/websocket.js

No dice. Left clicking and mousewheel still pause the websocket.onmessage. Needless to say, that is _super janky_ if it's even affecting a worker.

If you still aren't seeing it, try left-click dragging and rolling your mousewheel at the same time on the codepen example or caliber.online.

My game is basically unplayable in Chrome 50+. I feel your pain, zushiwar.
The pain is really deep. 
We were strugling with WebGL version of our Unity3d game for months. And when we finally got to release and started publishing - this bug arrived and killed 2/3 of audience. 

Week of diging this problem to find out that there is no work around and now it's here without priority and on triage...

Guys! THIS BUG IS A TOTAL KILLER for games with mouse and intense websockets. WITHOUT ANY WORKAROUND. Let's do something!

Comment 22 by ranz...@gmail.com, Apr 17 2016

Wrapping the websocket in a worker didn't help because _this affects worker.onmessage too_!

However, I've pinned it down to the ondragover event:

http://s.codepen.io/Ranzear/debug/grzzgg

Workaround, since I'm sure you're not using it:

window.ondragover = function(event) {
  event.preventDefault();
}

Comment 23 by ranz...@gmail.com, Apr 17 2016

Use this link instead:

http://codepen.io/Ranzear/pen/grzzgg

Something about the editor helps make it apparent.

Comment 24 by ranz...@gmail.com, Apr 18 2016

My workaround isn't sufficient to stop the lag on http://caliber.online, though it was enough on that codepen, so it's more than one event type stacking up.

My laptop still has the onmessage lag when playing Caliber, but couldn't get my codepen to demonstrate the behavior so I believe this is made worse by >60hz refresh rates, as I believe the move and drag events are created per screen refresh.

zushiwar: You wouldn't happen to have a 120/144hz monitor too? This would explain why we're having a much easier time seeing the bug in codepen when others don't, but our high-load games make it apparent to everyone.
window.ondragover = function(event) {
  event.preventDefault();
}

doesn't help me at all.. (tested in codepen)

in your example i've added some junk logging to the Loop to slow everything down  

for (var i = 0;i<100;i++)
     console.log(box.style.background);

and got the same issue - box keeps getting red while i drag mouse. 

and i've got 60hz laptop monitor, so i have to do that logging to drop fps. in case of 120hz - you may not even need it. 

Comment 26 by ranz...@gmail.com, Apr 18 2016

I didn't think to use console.log to generate lag. Indeed 120hz needs barely any load at all to get the blocked onmessage when dragging.

I forked that codepen so my continuing attempts wouldn't break it before anyone saw what I was working with. Here's my current setup where I've tried intercepting ondrag, ondragover, and onselect:
http://codepen.io/Ranzear/pen/VaxdvW

Notice that preventDefault on dragover isn't enough, but it is at least the biggest culprit, as the other two boxes lag as much as the first. You might have to turn up the console spam to see lag on the dragover box, but I still do.
I'm getting red in all 4 boxes 
I think all these preventDefault don't help because the problem is not in the way events handled but in the way they are queued or scheduled. Somehow these mouse events block all other.

Comment 29 by ranz...@gmail.com, Apr 18 2016

Yeah, if it was actually the events themselves this would all be showing up in the profiler.

I think the scheduling for these events is taking priority and hanging a function on one at least put it back on the regular scheduler, and it's the ones that are fired most that are blocking onmessage. Which ones are firing most depends on load and refresh rate though, so I do see a little improvement when intercepting ondragover (and why 120hz more easily craps out) but it's the whole pile of mouse-click and mouse-drag related events that are blocking it out in our applications.

Comment 30 by ranz...@gmail.com, Apr 18 2016

 Issue 450258  hinted at an interim solution, mentioning that using setInterval for frame timing avoided the onmessage block. I don't enjoy having a fixed framerate, but we're both starved for a fix, so I devised some code to alternate between requestAnimationFrame and setInterval (with the latter timed by the former). There is an fps penalty in Caliber (more that any skipped frame causes an extra to be skipped, so more #120hzProblems) but the onmessage block seems to be at least _mostly_ remedied for normal gameplay.

var altframe = true, frametime = 0, lastframe = Date.now();

function Run() {
	frametime = Date.now() - lastframe;
	lastframe = Date.now();

	if (!altframe)
		setTimeout(Run,frametime); // Hard-scheduled based on timing of last frame, must schedule before sim+render.

	/*

		SIM AND RENDER CODE

	*/

	if (altframe) {
		window.requestAnimationFrame(Run); // Normal timing, called after next paint.
		altframe = false; // Alternate frame will be timed based on the next one.
	} else {
		altframe = true; // Because we can't switch it above.
	}
};

Run(); // As if we just had our setTimeout fire, altframe should be true


So it seems this bug is also tied to using requestAnimationFrame, as mentioned in  Issue 450258  but not here yet.
Just using 
  setTimeout(Animate,1);
instead of 
  requestAnimationFrame
removes the problem in codepen. Tomorrow i'll try to patch unity3d generated code to see if it will work in game. 


Out of the fryin pan...

This fix removes websocket lag, but in fullscreen mode screen actually refreshes only once a second or so (even console). Though loop function is called well with 30-40 fps.
What's that thing? Do you have the same issue?

Owner: skyos...@chromium.org
Status: Started (was: Unconfirmed)
Thanks for the test cases guys. At least on caliber.online the problem seems to be that the wheel handler on the page doesn't prevent scrolling, so if you spin the mouse wheel Chrome thinks you want to scroll the page and modifies task priorities accordingly.

There's a bug which causes us not to go out of this mode when scrolling doesn't actually happen, which I'll fix. Meanwhile I believe a workaround is to add a call to event.preventDefault() in your wheel handler.
Ranz, does it help? ) 
In my cases there are no mousewheel things at all..
Something else to try: run Chrome with --disable-features=SchedulerExpensiveTaskBlocking and see if the issue goes away.

Comment 36 by ranz...@gmail.com, Apr 19 2016

Thanks for the tip. I just got done getting mousewheel events to work in Firefox (Mozilla flippantly renaming things again) and updating Firefox prompted me to update Chrome to 50 as well, bringing on the onmessage bug. return false; was originally enough, as that works on intercepting right-click too. That scrolling mode bug definitely sounds like why mousewheel exacerbated the onmessage block.

--disable-features=SchedulerExpensiveTaskBlocking appears to help on my laptop, but I need better performance to be sure. I'll double check on my big box during lunch.

Comment 37 by ranz...@gmail.com, Apr 19 2016

No dice with --disable-features=SchedulerExpensiveTaskBlocking on my main box (Win7). It might help a little, as I had trouble getting the bug without glfx or a lot of induced framelag, but here's video with and without glfx:

https://youtu.be/vLwYRJmqg3k

Circling mouse is when I'm left-clicking, using the laggiest tank possible. It looks like server lag at first but you see it all rush to catch up as soon as I let go. I believe each stacked onmessage comes out one-at-a-time per requestAnimationFrame once the left-click-drag block is relieved, because higher fps recovers faster, but how using setInterval or setTimeout gets around that I can't figure.

--disable-features=SchedulerExpensiveTaskBlocking
no help
any news here?
Sorry, I hope to get back to this next week.

One general comment here is that you might actually want to move WebSocket message handling to a WebWorker. Doing network communication on your UI thread is usually not a good idea regardless of what kind of scheduling we do.
The problem is, that messages from workers aren't delivered during lag just as websocket messages. 

And what's the profit, sending and receiving data to/from WebWorker instead of WebSocket? WebSocket api is non-blocking, why should we add some WebWorker proxy here? 
At least in the example I was looking at the UI thread getting spammed with more messages than it was able to process, causing the lag. The idea is that the WebWorker can do flow control and aggregation on the messages and send exactly one message to the UI thread per frame.
That would help but not too much. Often even 1 message can't break through

Comment 44 by ranz...@gmail.com, Apr 27 2016

This bug, as far I can tell, affects webworkers' onmessage exactly the same as websockets' onmessage. I discovered this when trying to move the socket into a worker back on Comment 20 or so, and even the examples I gave demonstrate with workers instead of websockets.

The .onmessage events _are not even fired_. This has nothing to do with their execution or performance.

I can explain to you exactly what's happening with the video linked in Comment 37:

Normally, the client receives updates from the server at a rate of 60hz. This isn't close to the most aggressive tickrate I've used. Dropping to 30hz or even 10hz didn't change the problem.

On each update from the server, the client decodes a game state from JSON, updates known objects, adds new objects, and deletes missing objects. Because Caliber is server-controlled-visibility, this is usually only a few dozen objects. After patching the game state, a mapping of the client's own tank's inputs is sent back, and this response gives the server a ping measurement as well. This order and determining of ping is important for later.

Between updates the client will simulate objects with their last known state. Tanks drive whatever inputs they were last given, bullets fly straight, missiles still track a locked target.

In Caliber and I'm sure zushiwar's game too, When you want to shoot somebody, you press LMB and move your mouse to keep your aim on them. This is why the LMB-drag bug is so far beyond a nuisance and straight into making the game unplayable.

What's happening when the LMB-drag block begins is that onmessage is _not even fired_, the incoming message is apparently just buffered or something. Caliber carries on simulating from the last known state, but things start to look odd. Eventually a single onmessage will get through every second or so (just for absolute clarity: every second, not every other frame or any other interpretation of 'second'. Rarely. Sporadically. Basically at random.) and the game state will jump way back to a far older state.

As some of these old(! fired in received order) onmessage events finally trickle through, responses are finally sent to the server and it calculates ping from the original timestamp of each, rocketing the value past a second or more.

This persists, simulating forward on old data, then a single onmessage leaks through and resets the state to a still-old state and updates the horrendous ping value, until the LMB-drag is released. Once the LMB-drag is released, onmessage starts firing again, but only fires each blocked onmessage, in order, at some seemingly fixed rate.

I postulated one onmessage per frame and you may have interpreted this as the bug, but this is the recovery state from  the bug itself. The bug causes onmessage to NOT FIRE except sporadically. The problem is NOT that we're getting one onmessage per frame, but that we're getting ~NONE~ per frame, followed by one per frame on releasing LMB.

Because no onmessage is even being fired, any overhead on the function called by onmessage is irrelevant. Offloading to a worker doesn't make a difference, and it affects workers too.

Are we perfectly, crystal clear on what this bug is yet? Do you understand our frustration that it makes our games absolutely unplayable? Do you see the _absolute insanity_ that clicking and dragging the mouse would cause onmessage events to NOT FIRE?

Comment 45 by ranz...@gmail.com, Apr 27 2016

You can't even discard the old onmessages, they just sit in buffer limbo until the LMB-drag ends and they start firing again in order.

The 'once per frame' was of interest because this is also tied to using exclusively requestAnimationFrame. Scheduling redraws or simulation with onTimeout or setInterval avoids the bug, but is far from ideal.

Heavy load in requestAnimationFrame is definitely some prerequisite to seeing the bug. Zushiwar achieves this with a Unity ported WebGL game, I do this with heavy PNG dataURL handling.

I can only speculate that LMB-drag is piling enough 'high priority' events after requestAnimationFrame that any onmessage is getting pushed to after the next RAF, and then pushed back indefinitely by the continuing LMB-drag, which is silly.

Somehow we're seeing a complete starvation of onmessage events by combination of requestAnimationFrame and LMB-drag.
My working assumption about what is happening here is that when Chrome detects a continuous user gesture that is handled by the main thread (e.g., LMB-drag), it starts giving priority to input processing and rAF to increase animation smoothness.

The problem in these examples is that rendering is heavy enough that it is causing starvation in other task sources. I can think of two fixes:

1. Never prioritize rAF. This would be simple, but would regress main thread animation smoothness.

2. Only prioritize rAF if it fits in the frame budget. This should handle both cases well.

In case someone wants to try it out, here's a quick hack for #1: https://codereview.chromium.org/1927883002
Experimental patch for #2 (not tested since I'm currently travelling):

https://codereview.chromium.org/1914373004
Is test build with this fixes available? 
Sorry, no, you'll need to build it yourself before the patch actually lands.
Cc: yhirano@chromium.org
Project Member

Comment 51 by bugdroid1@chromium.org, May 3 2016

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/6f3d26fe1385dc74f22bf2cf6bddc6830dd00d6c

commit 6f3d26fe1385dc74f22bf2cf6bddc6830dd00d6c
Author: skyostil <skyostil@chromium.org>
Date: Tue May 03 13:40:41 2016

scheduler: Only prioritize rAF if it is fast

To avoid starving other tasks, only prioritize main thread compositing (i.e.,
requestAnimationFrame) if there is more than 80% idle time left in a frame. This can
reduce animation frame rate on sites which can't keep up with the display refresh
rate, but will ensure other tasks (e.g., postMessage) aren't starved as a
side-effect.

BUG= 600385 

Review-Url: https://codereview.chromium.org/1914373004
Cr-Commit-Position: refs/heads/master@{#391221}

[modify] https://crrev.com/6f3d26fe1385dc74f22bf2cf6bddc6830dd00d6c/components/scheduler/renderer/renderer_scheduler_impl.cc
[modify] https://crrev.com/6f3d26fe1385dc74f22bf2cf6bddc6830dd00d6c/components/scheduler/renderer/renderer_scheduler_impl_unittest.cc

How long is the way for the fix from here to release build? 

Comment 53 by ranz...@gmail.com, May 3 2016

Keep an eye on http://www.chromium.org/developers/calendar

Just going by date of being committed on 5/3, it should already have hit canary (which is showing https://chromium.googlesource.com/chromium/src.git/+/5e216d9b62275101c30f4a5cb2174bb68970ef3c) or will by tomorrow.
Looks like 52.0.2724.0 is the first Windows canary which has the fix. Could you guys give it a spin and report back here?
Looks like issue fixed. Other players move smooth even while LMB pressed )

Labels: Merge-Request-51
Thanks for the confirmation. I'd like to port this fix to M51 too.
Labels: M-51

Comment 58 by tin...@google.com, May 5 2016

Labels: -Merge-Request-51 Merge-Approved-51 Hotlist-Merge-Approved
Your change meets the bar and is auto-approved for M51 (branch: 2704)
Project Member

Comment 59 by bugdroid1@chromium.org, May 5 2016

Labels: -merge-approved-51 merge-merged-2704
The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/bf63388e22acf3290e8c3eb8891dd8bfbcc3f86b

commit bf63388e22acf3290e8c3eb8891dd8bfbcc3f86b
Author: Sami Kyostila <skyostil@chromium.org>
Date: Thu May 05 12:50:55 2016

scheduler: Only prioritize rAF if it is fast

To avoid starving other tasks, only prioritize main thread compositing (i.e.,
requestAnimationFrame) if there is more than 80% idle time left in a frame. This can
reduce animation frame rate on sites which can't keep up with the display refresh
rate, but will ensure other tasks (e.g., postMessage) aren't starved as a
side-effect.

BUG= 600385 

Review-Url: https://codereview.chromium.org/1914373004
Cr-Commit-Position: refs/heads/master@{#391221}
(cherry picked from commit 6f3d26fe1385dc74f22bf2cf6bddc6830dd00d6c)

Review URL: https://codereview.chromium.org/1950913005 .

Cr-Commit-Position: refs/branch-heads/2704@{#382}
Cr-Branched-From: 6e53600def8f60d8c632fadc70d7c1939ccea347-refs/heads/master@{#386251}

[modify] https://crrev.com/bf63388e22acf3290e8c3eb8891dd8bfbcc3f86b/components/scheduler/renderer/renderer_scheduler_impl.cc
[modify] https://crrev.com/bf63388e22acf3290e8c3eb8891dd8bfbcc3f86b/components/scheduler/renderer/renderer_scheduler_impl_unittest.cc

Status: Fixed (was: Started)
M51 - Great!

Comment 62 by gsem...@gmail.com, May 9 2016

T-T Great

When does this update on pc chorme and android chrome..


i'm using 
51.0.2704.36 beta-m (64-bit)

Comment 63 by gsem...@gmail.com, May 13 2016

this happen same on android (windows ix fixed since 51.0.2704.47 beta-m (64-bit)

but android chrome is happening 

chrome's version is Chrome Dev 52.0.2723.0
and i tested  and not fixed...


Comment 64 by gsem...@gmail.com, May 13 2016

chrome and default browser on android is not fixing..


chrome-dev too
dev version is v52.0.2723.
normal version is v50.0.2661.89

window's version is fixed..
but not android version




Could you share a link to the page which is not working correctly?

Comment 66 by hyp...@gmail.com, Jul 2 2016

Thank you for the requestAnimationFrame prioritization fix, but this change has unfortunately introduced a serious problem for anyone who was or is still using setInterval as a workaround.


Previously, Chrome worked like this:

1. Definitely handle all pending setInterval/requestAnimationFrame calls.
2. ONLY if there's "room" left in the frame budget after #1 does Chrome handle pending onMessage calls.


It now behaves like this:

1. Definitely handle pending onMessage calls.
2. Definitely handle requestAnimationFrame calls.
3. Only if there's room left in the frame budget after #1 and #2 does Chrome call any pending setInterval function loops.


This is great for anyone who was already trying to use requestAnimationFrame, but it's VERY BAD for anyone relying on setInterval, because #3 often gets skipped now. The frame budget calculation seems to have been altered to take the length of the pending onMessage array into account. In my tests, I've seen that if there are too many onMessage calls pending on the current frame, then Chrome skips the setInterval function loop calls until the next frame.

This problem is made catastrophically worse by the fact that if there are enough onMessage calls pending at any given time, then Chrome PERMANENTLY blocks the pending setInterval loops from ever being called again! Once this bug kicks in, then behaviorally, it essentially acts exactly as if clearInterval() was called on all existing intervals.

(If I'm right about a pending onMessage count tracker influencing the new frame budget calculation, then maybe this is a thread concurrency problem? Maybe Chrome is subtracting from the pending onMessage count tracker in one thread while at the same time trying to add it from another thread, and by failing to synchronize manipulation of this value on a lock, the final value committed to memory winds up being permanently inaccurate? Or maybe the pending onMessage count is added to as if it's a 32-bit integer, but subtracted as if it's 8-bit, so if it ever exceeds 255 it never actually gets reset to zero?)

Rather than playing around with priorities, maybe a better solution would be to instead completely divorce WebSocket onMessage handling from the redraw thread. Why not directly handle it at the synchronous javascript engine level? All pending onMessage data could be processed right at the beginning of the next frame of javascript logic, rather than competing with redraw events for a chance at being called at all.

Comment 67 by ranz...@gmail.com, Jul 2 2016

Definitely a fundamental issue with the event queue if it's able to completely starve any source of event calls.

To be honest, setInterval needs to die for anything under 100ms. requestAnimationFrame exists exactly because setInterval was too often employed as 'per redraw'. Interval times below even half a second but not redraw related aren't likely to need such precision; you could instead check a 'time since last operation' in an rAF call.

Yes, this is definitely still an event scheduling issue. My opinion is that if you're having an issue with setInterval starvation, you need to first look at why you're still using setInterval.

Comment 68 by hyp...@gmail.com, Jul 3 2016

As you touched on in Comment 30, the reason for using setInterval was to get around the WebSocket onMessage bottleneck bug in the older version of Chrome, because the bottleneck became a serious issue when requestAnimationFrame was used.

Now with this broken update, we are forced to use requestAnimationFrame instead to make our game work, because setInterval is no longer an option thanks to the new bug. Of course, this breaks the game for anyone who hasn't updated Chrome to the current version yet.

If simply using onMessage with a WebSocket or WebWorker is enough to permanently block any currently-running interval function calls under certain conditions, then this new bug must be manifesting in strange ways all over the place. I've noticed many advanced sites like YouTube are also randomly breaking lately in unusual ways that require a tab refresh, and only in Chrome. I wonder if it's related to this.

Comment 69 by ranz...@gmail.com, Jul 3 2016

Does it also occur with setTimeout? My first proper workaround of the original issue was there in #30 too; a hybrid approach of alternating requestAnimationFrame(sim) and setTimeout(sim, timeSinceLastrAF). You could give that a try in the meanwhile.

At the time I was also devising a way to detect the blocking and fall back to the hybrid method. Just checked a timer since last socket.onMessage and switched a boolean from pure rAF to hybrid.
Do you have links to pages that don't work correctly? Let's file a new bug for the issue you are seeing.

Comment 71 by hyp...@gmail.com, Oct 3 2016

I am still seeing this problem in Chrome 53.0.2785.116:

When you click the mouse and drag around during a period when requestAnimationFrame is doing heavy lifting, it consumes the remaining idle time in the frame, and any pending local WebSocket onMessage calls become clogged.

When you release the mouse, all of the pending onMessage calls are suddenly processed all at once. It falsely behaves as if there was intense network lag coinciding with use of the mouse button.


Maybe look into the code near "ShouldPrioritizeInputEvent" in the file "renderer_scheduler_impl.cc", where you can see these comments in that function:

// We regard MouseMove events with the left mouse button down as a signal
// that the user is doing something requiring a smooth frame rate.

In that case, it returns "true" for the function "ShouldPrioritizeInputEvent". I believe returning "true" there is what is unfortunately acting as permission to block all incoming WebSocket onMessage calls during heavier requestAnimationFrame use.
hypah2@: We only prioritize rAF it is fast[1] which should avoid the situation you described. Could you try again on M54 or later? Also, a link to a broken page would be helpful if possible.

[1] https://cs.chromium.org/chromium/src/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.cc?rcl=0&l=862

Comment 73 Deleted

Comment 74 by tomfr...@gmail.com, Oct 24 2016

I think I'm seeing this issue still on Chrome 54.  I've created a codepen to reproduce it, the websocket server is running on heroku so it might take a few seconds to start up:

http://codepen.io/tomreay/pen/Gjzwvb

If you scroll using the mouse wheel in the scrollable div slowly you should see the correct behavior of:

Sending 1
1 response
Sending 2
2 response
Sending 3
3 response
Sending 4
4 response
...

However if you scroll very quickly you instead see:
Sending 1
Sending 2
Sending 3
Sending 4
Sending 5
Sending 6
...

When you stop scrolling, or slow down, you will get a batch of responses in one go.  One interesting thing to note is that on my local machine after a while of the requests being batched up it will suddenly change and behave correctly, however refreshing the page will reset it back to the broken behavior.

I seem to have a similar issue in Chrome 56.0.2924.76 (64-bit, Windows 7). When using the mouse wheel to scroll, the websocket events seem to queue-up and are fired once the scrolling operation is completed. Scrolling via the scrollbar or via keyboard works. 

The used webpage contains multiple webgl contexts, but I doubt that this is the source of the problem.

Any advice? Dropping the mouse wheel events helps, but is of course not a solution!

Thanks in advance!
#74: Looks like the problem is that the overflow div is getting fully repainted on every scroll, which means we'll try to prioritize that over other tasks to try to maintain a smooth framerate. I'm not sure why that is happening on this particular page -- perhaps codepen is injecting some styles that cause this.

Here's a quick guide for investigating scrolling repaint issues with DevTools: https://developers.google.com/web/updates/2016/09/devtools-digest

Sign in to add a comment