Receiving large binary websocket messages consumes too much CPU




Networking: WebSockets
4 months ago
2 months ago


(Reporter: badkins79, Unassigned)


55 Branch

Firefox Tracking Flags

(Not tracked)


(Whiteboard: [necko-triaged])


(1 attachment)

154.19 KB, application/x-xz


4 months ago
User Agent: Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.75 Safari/537.36

Steps to reproduce:

I have a canvas tag that covers the whole page. I also have a websocket open to an application running locally on the same computer. That application is sending a stream of raw uncompressed image data which is plopped onto the canvas in the correct location as they arrive. 

Actual results:

On Windows especially, but also on Linux and Mac, the Firefox process consumes enormous amounts of CPU just by receiving these WebSocket messages. I have commented out the part in the JS where the data is placed onto the canvas entirely, and it makes no difference. It is just the receiving piece that is causing the problem.

A common test case has it receiving a stream of video frames for a 480x360 video, so each websocket message payload is 691,200 bytes long. I am trying to send 30 frames a second, but Firefox just can't keep up.

Expected results:

The local application responsible for generating this image data AND sending it through the websocket consumes hardly any CPU. There is no reason for Firefox to consume more than the sending process when it is receiving that same data. Firefox should be able to receive large websocket messages without swamping the CPU.


4 months ago
Component: Untriaged → Networking: WebSockets
Product: Firefox → Core
Created attachment 8903864 [details]

Do you have any test case that shows the problem? I used attached test to try to reproduce it, but I see no problem receiving 30x691200 bytes per second.
Flags: needinfo?(badkins79)

Comment 2

3 months ago

Thank you so much for looking into this. Please stand by while we try to run your test app in our environment to see how it behaves.
Flags: needinfo?(badkins79)

Comment 3

3 months ago
So we tried this out. We made a few tweaks in the server config to magnify the issue.

If modify wsserver.js:
Change packetLength to 1800000
Change totalPackets to 3000

When we run that on one of our test machines with 3GHz processor, we see 2 Firefox processes running. One consumes around 33% of processor power, and the other consmumes around 10%. In comparison, the websocket server application that is sending this data is consuming less than 5%.

On this machine, Firefox does keep up, but on a machine with a weaker processor, Firefox overwhelms the system. Sadly, I don't have a means of profiling Firefox to see what it is doing to take up so much processor. Just reading bytes off the socket should not be processor intensive. But I just don't see what else it could be doing. Perhaps it is in the code that takes the fully received message and then sends it into the Javascript for the onMessage call.
Do you have any next steps for this issue?
Flags: needinfo?(michal.novotny)
Priority: -- → P3
Whiteboard: [necko-triaged]
I retested this on Acer reference notebook with packetLength 1800000 on Linux with Firefox nightly and Chrome stable. vmstat shows ~75% idle in case of Firefox and ~53% idle in case of Chrome. If we can find somebody to have a look if there is some room for improvement we can keep this open with P5 priority, otherwise it's WFM.
Flags: needinfo?(michal.novotny)
Priority: P3 → P5
You need to log in before you can comment on or make changes to this bug.