wire-desktop
wire-desktop copied to clipboard
Poor performance on Linux
Wire version: 3.6.2885 (latest from deb https://wire-app.wire.com/linux/debian stable main
)
Wire for web version: -
Operating system: Debian GNU/Linux 9.8 (stretch) Linux 4.19.0-0.bpo.2-amd64
Which antivirus software do you have installed: -
What steps will reproduce the problem?
- Start
wire-desktop
- Make a video call
What is the expected result?
Reasonable CPU and RAM usage.
What is the actual result?
Enormous CPU and RAM usage to an extent where the system becomes unresponsive and the frame rate of the video call drops to about 2 FPS.
Please provide any additional information below.
Screenshot of htop
while I'm in the video call.
#661 might be related. I'll try the fixes proposed there but I can only confirm a duplicate once I make another video call (probably tomorrow).
I have applied the fix proposed in #661, namely to define the environment variable ELECTRON_FORCE_WINDOW_MENU_BAR
. This improved the performance insofar that Wire now “only” uses 90% instead of 100% on all cores. The memory consumption was also improved a little and the rest of system is no longer unusable while I'm talking on Wire. Unfortunately, the Wire application itself remains barely usable. After entering the call the video frame rate drops to about 2 FPS within the first minute. The whole interface is reacting slowly.
Hi @hmenke, do I see correctly that you have ~4 GB of memory?
@ffflorian Yes, I have 4GB of physical memory and 10GB of swap. However, memory doesn't seem to be the problem, especially after applying the fix from #661 which improved idle performance of Wire a lot! Is there a way to profile Wire to see where it is spending the most time? Is there something like a compiler switch like -pg
for GCC to generate instrumentation for gprof
?
Is there a way to profile Wire to see where it is spending the most time? Is there something like a compiler switch like
-pg
for GCC to generate instrumentation forgprof
?
Not as far as I know, that would be a thing for Electron to implement.
Also please note that the Linux executable is still experimental.
I'm having an issue where leaving it running for a long period (1-2 days) will take up most of my mem and CPU (up to 12 gb of memory). I'll provide some more details next time I leave it running - looks similar to the performance problems you're having.
Electron (or rather V8) comes with a profiler. One can dump profiling data by starting Wire with
wire-desktop --js-flags="--prof"
This will generate a couple of isolate-<xyz>.log
where <xyz>
is a process ID. These can be analyzed with V8 tools. I haven't had a chance to try that yet, but I will report my findings.
Source: https://v8.dev/docs/profile
Thanks @hmenke, I was not aware of that.
I have extracted the profiling from my recent Wire call. All the logs can be found below. Unfortunately, I don't know which one of these is the main process, but I think it is isolate-0x384b37dac000-v8.txt. In there I see something which is a bit worrying:
<...snip...>
[C++]:
ticks total nonlib name
1051554 56.2% 92.2% poll
36718 2.0% 3.2% madvise
24784 1.3% 2.2% writev
<...snip...>
It looks like Wire is performing an enormous amount of I/O, because this generates two orders of magnitude more ticks than any other operation.
isolate-0x289ef7cf2000-v8.txt isolate-0x289ef7cfe000-v8.txt isolate-0x289ef7d0a000-v8.txt isolate-0x289ef7d00000-v8.txt isolate-0x289ef7d02000-v8.txt isolate-0x289ef7d03000-v8.txt isolate-0x289ef7d04000-v8.txt isolate-0x289ef7e53000-v8.txt isolate-0x289ef7e55000-v8.txt isolate-0x289ef7e56000-v8.txt isolate-0x384b37dac000-v8.txt
Okay, to get only a single log file you have to launch Wire with
wire-desktop --js-flags="--prof --no-logfile-per-isolate"
This will create a single v8.log
.
Unfortunately, the output is also a lot less informative for some reason.
$ tick-processor v8.log
Statistical profiling result from v8.log, (46830 ticks, 0 unaccounted, 0 excluded).
[Shared libraries]:
ticks total nonlib name
21 0.0% /opt/Wire/wire-desktop
[JavaScript]:
ticks total nonlib name
[C++]:
ticks total nonlib name
46786 99.9% 100.0% __pthread_cond_timedwait
9 0.0% 0.0% write
2 0.0% 0.0% v8::internal::Factory::InitializeJSObjectBody(v8::internal::Handle<v8::internal::JSObject>, v8::internal::Handle<v8::internal::Map>, int)
2 0.0% 0.0% fwrite
2 0.0% 0.0% _IO_vfprintf
1 0.0% 0.0% mprotect
1 0.0% 0.0% memcpy
1 0.0% 0.0% fflush
1 0.0% 0.0% __pthread_cond_wait
1 0.0% 0.0% __lll_unlock_wake
1 0.0% 0.0% __libc_send
1 0.0% 0.0% __clock_gettime
1 0.0% 0.0% _IO_file_xsputn
[Summary]:
ticks total nonlib name
0 0.0% 0.0% JavaScript
46809 100.0% 100.0% C++
0 0.0% 0.0% GC
21 0.0% Shared libraries
[C++ entry points]:
ticks cpp total name
1 100.0% 0.0% TOTAL
[Bottom up (heavy) profile]:
Note: percentage shows a share of a particular caller in the total
amount of its parent calls.
Callers occupying less than 1.0% are not shown.
ticks parent name
46786 99.9% __pthread_cond_timedwait
Even without a video call, Wire idles at 35 % CPU usage. That'd probably be okay on a really old CPU, but a Core i5 isn't that old. And it eats 5.8 GiB of my 8 GiB of RAM.
Again, this is just having the application running in the background seemingly not doing much.
Even running several virtual machine takes less ressources. o.O
Do we have at least a workaround since there is no fix yet?
I got pissed enough that I actually wanted to look why renderer east CPU all the time.
The answer is layer with spinner which is always there.
It triggers style recalculation and composition constantly.
I can't say we didn't have the same issue in our app but this should be fixable?
I tried to modify LoadingSpinner to just return null
and indeed all the repaints are gone. Silence has entered our office and my blood pressure went down.
The spinner is rendered when the account is visible:
https://github.com/wireapp/wire-desktop/blob/126be5488b8259973b259a7cb04efa5f7b683453/electron/renderer/src/components/Webview.jsx#L210
which it always is when it's selected I assume so it's always rendered.
@charlag I think I love you.
Wire team, please take note that if you devote just a few resources into performance improvements it is way better for the userbase than fancy features that 1% of the users will use.
100% of the users will enjoy longer battery life and more available CPU.
Pull request #5164 attempts to remove the LoadingSpinner contents from the DOM after the spinner has faded out. It seems to lower the idle CPU usage considerably - at least on Macs. Huge thanks to @charlag for tracking down the culprit 🙂
Since 2022.09.20.08.41 (or 3.28.2946) Wire does not hang anymore when pasting an image into the input field. I don't know what you've changed but before I always had to wait up to 20-30 seconds (depending on the image size) until the desktop client was responsive again after pasting an screenshot. Now I can paste images within one seconds which is nice. Thanks!
It was indeed massively reduced with #5164 Sorry that it took so long!