Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Run plugins asynchronously (EditorConfig and other plugins slowing down Code) #1314

Open
ghost opened this issue May 8, 2023 · 29 comments · May be fixed by #1334
Open

Run plugins asynchronously (EditorConfig and other plugins slowing down Code) #1314

ghost opened this issue May 8, 2023 · 29 comments · May be fixed by #1334

Comments

@ghost
Copy link

ghost commented May 8, 2023

What Happened?

Some plugins slow down Code a lot, to the point that Code is barely usable in weak CPUs.

Steps to Reproduce

In a weak CPU (like a Raspberry Pi or a Chromebook):

  1. Get Code
  2. Enable some plugins
  3. See slowdown.

Expected Behavior

This does not happen in heavier text editors that do more stuff like VSCode because each extension runs in its own thread. Maybe we could get some ideas from them?

OS Version

7.x (Horus)

Software Version

Latest release (I have run all updates)

Log Output

No response

Hardware Info

Chromebook: Intel Celeron N4020 4GB RAM 32GB eMMC.

@jeremypw
Copy link
Collaborator

Would be possible to identify a plugin that slows Code down particularly badly or is it a combination of plugins?

@ghost
Copy link
Author

ghost commented May 14, 2023

I don't think a particular plugin is the problem. There are always memory leaks. However one slow tab on Chrome doesn't slow it down or crash it, same with VSCode. So my opinion is the problem is plugins run synchronously with the code editor.

Even when all plugins are disabled, Code runs worse than Gedit and other editors, and is marked as "consuming lots of energy" by elementary. Don't know why.

@jeremypw
Copy link
Collaborator

The Git integration (which is in the main code) probably uses significant power for a large repository.

@jeremypw
Copy link
Collaborator

You could try turning off "Autosave" to stop documents continually being saved while being edited.

@ghost
Copy link
Author

ghost commented May 14, 2023

I'll try that. However git integration in vscode is more complete and works fine without using much power.

@ghost
Copy link
Author

ghost commented May 16, 2023

Disabling the situation makes the text editor run much smoother. However in my opinion Code should remain simple in its core and extend itself with plugins (so no Git integration in the core for example)

@jeremypw
Copy link
Collaborator

jeremypw commented May 16, 2023

What do you mean by "disabling the situation"? Do you mean turning "Autosave" off?

Are you working on a git repository? The git integration should not consume power if you are not. We can look for inefficiencies in the git integration. Code is targeted at editing code in git repositories so that does need to be efficient. Improving git integration completeness is one of our aims.

@jeremypw
Copy link
Collaborator

We could look at options to disable some aspects of git integration like real time updating the git status of each line in the document which slower machines might struggle with.

@ghost
Copy link
Author

ghost commented Jun 15, 2023

Closing tabs is also slow (takes something like half a second or 1 second). It shouldn't be this way, even when plugins are enabled.

@jeremypw
Copy link
Collaborator

@aitor-gomila How many tabs are we talking about? Or is it half a second per tab? How large a document? I find closing a single tab containing <2000 lines in the master version virtually instantaneous with an SSD. A certain amount of checking goes on before the tab closes.

@ghost
Copy link
Author

ghost commented Jun 15, 2023

Maybe more like 1-2 seconds per tab. Documents aren't longer than 200 lines. It's a chromebook with an eMMC. I know an SSD is recommended but the OS in general works fine, blazingly fast. It's just the Code app.

@jeremypw
Copy link
Collaborator

Usage of cpu on my computer is virtually undetectable when just closing one tab (<0.2% for a fraction of a second) this is with all plugins on, symbol pane showing and using a git repo (Code itself) but it might be worth you running Gnome System Monitor while you close tabs to see what is rate limiting.

@ghost
Copy link
Author

ghost commented Jun 15, 2023

Opening and closing a file with 20 LOC will ramp up CPU power usage to 100% and go down once the UI is not freezed anymore
Screenshot from 2023-06-15 17 22 38

Changing settings and everything else will affect CPU usage too, other than idling.

Disabling all plugins and settings and restarting seems to have fixed this, though as I say, a badly written plugin shouldn't affect the IDE itself and its core features.

P.S: I disabled "editorconfig" plugin. Looking at its source code, it reads from editorconfig on "hook document", which is I suppose, open document? For some reason, this is freezing the UI, it should be async.

In a desktop CPU it's not as noticeable, however you'll notice if you disable all plugins closing tabs will feel noticeably snappier (Ryzen 7 2700)

@ghost ghost changed the title Some plugins heavily slow down Code Run plugins asynchronously (EditorConfig and other plugins slowing down Code) Jun 15, 2023
@jeremypw
Copy link
Collaborator

@aitor-gomila Thanks for the investigation! So it looks like the editorconfig plugin is mainly responsible? I'll look at the code to see if there is an obvious inefficiency or whether it can be made async.

@jeremypw
Copy link
Collaborator

jeremypw commented Jun 15, 2023

Looks like that plugin is re-parsing the document when it is refocused not just when it opens which seems excessive since it is unlikely the .editorconfig file has changed while unfocused. Closing a document focuses another one which triggers the plugin hooks but that should only happen after the tab closes. Closing a document will trigger it to be saved if there are unsaved edits but that happens asynchronously.

@ghost
Copy link
Author

ghost commented Jun 15, 2023

"It's unlikely" is bad programming in my opinion. Maybe we can watch ".editorconfig" for changes and send that to all documents in the same directory. Would that be feasable in your opinion? Because maybe this solution is overcomplicated.

@jeremypw
Copy link
Collaborator

jeremypw commented Jun 15, 2023

Yes, I was thinking of monitoring the .editorconfig file. I wasn't proposing to ignore the possibility of the file changing - just deal with it better. The parsing should not be that onerous though for normal size documents so I am not sure this explains the slowness.

@jeremypw
Copy link
Collaborator

jeremypw commented Jun 16, 2023

@aitor-gomila Could you confirm that the problem appears even if the only plugin enabled is editorconfig and disappears if that plugin is disabled? I would not expect that plugin to be so cpu or io hungry.

@jeremypw
Copy link
Collaborator

jeremypw commented Jun 16, 2023

Also, is simply switching from one tab to another equally slow? That also triggers the plugin. Is closing an unmodified document as slow as closing a modified one? Does it make a difference whether or not the documents are part of a git repository?

@jeremypw jeremypw linked a pull request Jun 16, 2023 that will close this issue
@jeremypw
Copy link
Collaborator

@aitor-gomila I have pushed a draft PR #1334 for trying to address this issue. At the moment it just makes the editorconfig plugin asynchronous. If you are able to compile and install this PR to see whether it makes a difference to you that would help.

If you know how to use gdb you could try running Code under gdb and press <Ctrl>C while the interface is frozen when closing a tab (use documents that are not valuable or are backed up). You can then press bt to see which part of the code is running. This is best done on code compiled from source with debug symbols. The tabs close too quickly on my machine for me to do this.

@ghost
Copy link
Author

ghost commented Jun 16, 2023

Hi again. Yes, I can still reproduce, though now it is much better (freezes for an instant, maybe 0.25s). Maybe I had gotten a memory leak. It is more reproduceable when opening a large quantity of files (8) than a tiny quantitiy of files (2).

Do you think it would be feasible to create and maintain a plugin API?

@jeremypw
Copy link
Collaborator

I guess something could be put in the wiki.

I am looking into setting up a VM to emulate a slow cpu computer - if I succeed I hope to be able to locate bottlenecks more easily.

@ghost
Copy link
Author

ghost commented Jun 16, 2023

I am compiling your branch. How do you get gtksourceview-4?

P.S: I can reproduce the freeze /slowness when opening, switching and closing files. Could something in the source code be made async so it doesn't block the UI? I have taken a look at it and want to contribute, but don't know where to start right now. Will take a look later.

@jeremypw
Copy link
Collaborator

you should be able to get the dependencies with sudo apt build-dep io.elementary.code

@ghost
Copy link
Author

ghost commented Jun 16, 2023

Thanks! Getting this now (when running the application)

(io.elementary.code:5840): GLib-GIO-ERROR **: 21:45:36.243: Settings schema 'io.elementary.code.settings' does not contain a key named 'wholeword-search'
[1]    5840 trace trap  ./src/io.elementary.code

I have a question. In Vala, if a method isn't marked async in a Service, does it block the UI? Can we test this, with something that takes long (e.g. Future.delayed(20); in Dart which returns the future in 20 seconds). Maybe this way you can test if it's the open/close file service or some plugin.

@jeremypw
Copy link
Collaborator

The message about settings suggests that you havent installed the application (sudo ninja install) and the settings schema differs from the version you are running. Another setting must have been introduced since the last stable release so you need to install the new schema.

In answer to your async question my understanding is that it depends on whether it was called by an async process. If it was not called by an async process and if it takes a long time itself or calls a blocking method (e.g. non-async i/o) then it is liable to block the UI.

@jeremypw
Copy link
Collaborator

Note: the open and close document methods are already async. Even async methods can slow down the interface though if they hog the cpu.

@jeremypw
Copy link
Collaborator

I found things slow down considerably if memory is short because the computer is continually swapping things with the disk. So you might want to check that.

@ghost
Copy link
Author

ghost commented Jun 17, 2023

I'm good at memory. I think it's cpu that's bottlenecking. This does not happen in vscode or, at least, there are not visual freezes there. Neither on Gedit.

These and others are not async. I'm convinced this specific method is not the cause, though.

For example, loading content IS async, but moving a file or copying a file isn't. This is not to say THAT is the cause of the slowdown.
Screenshot from 2023-06-17 11 25 45

P.S: As of now, with your PR, it is working much better, but hang on because it might appear later.
P.S: Even when running short of memory, 1.2GB swap, switching tabs is flawless now

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant