tjhrulz / WebNowPlaying-BrowserExtension

The extension to go along with the WebNowPlaying plugin for Rainmeter
74 stars 35 forks source link

Anyone else noticing musicInfo latency for inactive tabs in firefox 82? #52

Closed aminomancer closed 3 years ago

aminomancer commented 4 years ago

Just thought I'd ask to see if it's just me. This just started this week for me, and I'm getting the same bug with my own fork as well as the original. With media playing in an inactive tab (e.g. some other tab is selected/focused/whatever), if I hit play/pause, the media instantly plays/pauses but rainmeter receives the info update 2-3 seconds later. For some reason, the lag is a lot longer when pausing from a played state than it is when playing from a paused state.

If I select the tab that's playing the media and do the same thing, the latency is gone. I'm totally convinced this is not caused by javascript/DOM throttling because there's a delay before those systems define an inactive tab as idle and start throttling it, and even if there wasn't, the 2-3 second delay is way more severe than you'd get from idle throttling. Plus javascript throttling has been around forever, and this just started recently.

I also did some testing to see if it was on the plugin's or rainmeter's end. I can't completely rule it out but I have confirmed with timestamps that the messages are being sent late, not being received late.

So my suspicion is this is a firefox regression, something must have changed in how it handles websocket messages from content scripts running in inactive tabs.

I'm also getting another (presumably unrelated) bug, as evidenced by error messages in the rainmeter logs:

System.FormatException: Input string was not in a correct format.
   at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
   at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)
   at System.Int16.Parse(String s, NumberStyles style, NumberFormatInfo info)
   at WebNowPlaying.Measure.WebNowPlaying.OnMessage(MessageEventArgs arg)
WebNowPlaing.dll - Error converting duration into integer

And yeah the spelling WebNowPlaing.dll is verbatim copied from the logs. I haven't looked much at the plugin source code but since I forked the browser extension I'm positive this misspelling isn't present anywhere in the extension, it is probably in the plugin? These error messages primarily occur when the browser extension stops/starts/updates or the browser itself quits. However, on one occasion I got these error messages randomly while just watching a youtube video and it caused a massive display bug, like characteristic frozen glitch artifacts on screen and the music stuttering rapidly in that loud, startling way like you might get before a blue screen of death. It did that crazy glitch clusterfuck stuff for like 3 seconds and then went back to normal lol. I would never have guessed it had anything to do with rainmeter or webnowplaying plugin, so it wasn't until a bit later when I actually checked the log and saw the error message exactly coincided with the display bug. Maybe it's a rainmeter bug honestly because idk how the plugin could possibly do that.

tjhrulz commented 3 years ago

If I had to guess what is almost certainly happening is that the webpage itself is not being drawn as often. This makes sense because you said that the pausing of the music happens instantly and the response saying it has paused it what is delayed.

WebNowPlaying does not assume that if it commanded a pause that it actually did pause it will only receive that info when the webpage itself actually updates showing it visually has having paused. I am curious what site it was with though.

Regardless since this is a firefox regression for saving CPU cycles there probably isn't much I can do here. So given that it I am gonna close the issue but still feel free to have more discussion.

aminomancer commented 3 years ago

Thanks for the response. I don't know the reason for this but I think I figured out a solution. I'm still not sure what exactly changed, but the problem is solved by changing these prefs: dom.min_background_timeout_value dom.min_background_timeout_value_without_budget_throttling

They both default to 1000ms. I actually was able to fix it by just changing the second one, but under some conditions the first one works as well. It seems like changing the second one negatively impacts performance more than the first one, but the first one doesn't work all the time. From what I've been able to glean it seems like these configure a value that firefox substitutes for any setTimeout/setInterval method below its value in a script running in an inactive/background tab. So a setTimeout(100) is turned into setTimeout(1000) when you tab out. Judging by the pref names, I think the second one is the default value that's normally active, and the first one is a special value that is used when "budget throttling" is enabled.

I looked through firefox's source code a bit to find out about this, it seems like it measures javascript engine's performance and at a certain point turns on this really elaborate system which sort of dynamically throttles execution by adding and subtracting to/from this virtual budget with every operation. So I set the second value to 50, making the musicInfo feedback pretty much instant all the time. I think theoretically it's possible that performance could drop so much that it would use the first value instead, but since I only use rainmeter on a fast PC, I haven't run into that yet.

Given that these settings have existed for a very long time, and since before they were 1000 they were actually 2000, I'm not sure what changed. My first assumption was that something on YouTube changed, since that's where I first noticed it. So I messed with the extension's youtube script, and some selectors needed to be updated as well and I included some provisions for embedded youtube iframes, but was not able to affect the websocket timing.

But then I noticed that the problem was actually universal, like on netflix and even sites for which the generic script is called. So I figured it had to be a firefox regression. My guess is something changed in what firefox perceives as a "timeout" or "interval" which has a global impact on media players. Maybe the playing of media was not previously so integrated with javascript, but that's really far beyond my area of expertise.

tjhrulz commented 3 years ago

Yeah its though to pinpoint exactly but if I had to guess you are on the right track, its either a regression, and purposeful change to help mitigate various attacks that require a high degree to tight timing control like Spectre or Meltdown, or it is just something Firefox has had for a while and only just started enforcing to conserve CPU cycles and thus battery life.

Overall this is just something we kinda want to keep an eye on but it will affect this extension just as much as the sites it runs on so hopefully it wont get to bad, this is just one or those things that even when the tab is inactive it still needs to run at full speed since you still see the result of it (Which as an assumption that is different for most website as we could never update it when you dont see it and you would never know).