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

Decorations flickering on editor change #136241

Open
memeplex opened this issue Nov 1, 2021 · 10 comments
Open

Decorations flickering on editor change #136241

memeplex opened this issue Nov 1, 2021 · 10 comments
Labels
editor-api Issues about the API of vscode in the area of editors feature-request Request for new features or functionality
Milestone

Comments

@memeplex
Copy link

memeplex commented Nov 1, 2021

Does this issue occur when all extensions are disabled?: Yes

  • VS Code Version: 1.61.2
  • OS Version: macOS Big Sur 11.6

I've recently been trying to optimize an extension that decorates [[...]] wikilinks in markdown documents. Every time I switched between editors a very noticeable flickering happened because of the syntax rehighlighting of the editor and, not so shortly after that, a delayed repainting of decorations. I checked other similar extensions and the pattern was always the same. It's even suggested in this "official" example: https://github.com/microsoft/vscode-extension-samples/blob/main/decorator-sample/src/extension.ts. There are two problems:

  1. The suggested delay of 500ms might be reasonable for in-editor changes but for editor switching it produces this: Long delay in link highlighting foambubble/foam#805 (comment).
  2. Even with no throttling at all and with precalculation and caching of document decorations (that I roughly implemented here perf: Avoid recomputing decorations svsool/memo#479) there is the same repainting glitch, although it's less obvious.

The second point is likely the hard one because it might be due to a more structural limit of the design. Why is VSCode triggering document-wise updates of decorations in unchanged documents? From the perspective of the extension author, is there any way to do that update incrementally, some knowledge of damaged/exposed chunks?

N.B. in the above cases extending the syntax was also problematic, for example because of the need to distinctively decorate valid and invalid links. Even if the syntax extension approach were effective here, the point still stands that decorations seem ill-suited for anything but small documents and even in those documents they produce visual artifacts on editor switching.

@memeplex
Copy link
Author

memeplex commented Nov 1, 2021

This is an interesting example that shows the issue with three different extensions that use decorations with different delays:

Screen.Recording.2021-11-01.at.18.12.57.mov

(the strikethrough effect is kind of cool though, like it's striking the word through XD)

@alexdima
Copy link
Member

alexdima commented Nov 3, 2021

You are correct, the current approach to text editor decorations is to clear them when the text model is detached from the code editor (i.e. when switching tabs). Here is how decorations work internally:

  • when having 10 tabs opened, there is one editor instance and 10 text model instances.
  • when having a side-by-side layout, there are two editor instances running/
  • when switching tabs, a text model instance is "detached" from the editor and the new one is "attached" to the editor.
  • decorations live on the text model. They move and stick with the text.
  • the same model can be attached to multiple code editors at the same time (e.g. seeing the same file side-by-side).
  • when setting decorations on the text model, they can be added with an ownerId. When the ownerId is 0, the decorations render in all code editors where the text model is attached. An example for this would be diagnostics/squiggles which exist once on the text model and get rendered in all editors.
  • most of our decorations use a real value for the ownerId, the editor instance if. This allows that the same file can be displayed in two editors and shows different decorations. Each editor renders the decorations which have a matching ownerId or an ownerId equal to 0. A simple example for this are find matches where the same file can be opened side-by-side and searched at the same time with different strings.
  • we have decided to remove all decorations associated with the current editor when a text model detaches. This is what causes that decorations get removed. The reason for this is that we have been plagued by leaking decorations. Decorations are very popular even internally and very many places simply forget to clean up properly after themselves. One example would be you'd search across files for something, and every time a file would be revealed, more and more decorations would get added, but never removed.
  • our internal API is different than our extension API (it was done earlier, so we had a chance to learn from that). In the extension API it is unlikely that folks would leak decorations, unless they always create new text editor decoration types, while in our internal API anyone can keep on adding decorations and they are not grouped by a type.

I am not quite sure how we could improve things, perhaps by having a "persistent" property or something on these decorations that should survive across detaching / re-attaching a text model to a code editor.

@alexdima alexdima added editor-api Issues about the API of vscode in the area of editors feature-request Request for new features or functionality labels Nov 3, 2021
@memeplex
Copy link
Author

memeplex commented Nov 3, 2021

Thank you very much for the detailed answer @alexdima, I understand your points, I'm giving a heads up to extension developers that I believe may be interested in this.

@memeplex
Copy link
Author

memeplex commented Nov 3, 2021

One thing that may be changed in any case is the reference example: the problem is made worse because extension developers may be copying a recipe that delays redecoration by 500ms even on editor switch.

@alexdima
Copy link
Member

alexdima commented Nov 4, 2021

@memeplex I agree that the example is flawed, as it artificially delays computing decorations when switching editors. Would you be willing to contribute a PR to improve it?

@memeplex
Copy link
Author

memeplex commented Nov 4, 2021

Sure @alexdima I'm pretty busy right now but I'll give it a try in a few days.

@memeplex
Copy link
Author

@alexdima please see https://github.com/microsoft/vscode-extension-samples/pull/535/files. I'm not sure if there is any advantage in using a timeout of 0 (vs directly calling the refresh as I did).

@yg-i
Copy link

yg-i commented Jun 8, 2024

One thing that may be changed in any case is the reference example: the problem is made worse because extension developers may be copying a recipe that delays redecoration by 500ms even on editor switch.

Does calling setDecorations immediately upon active editor change [1] actually eliminate the 500ms delay?

If I understand the exchange correctly, and if my own testing is reliable, the 500ms or so delay appears to be unavoidable, at least as things currently stand?

[1] as in:

vscode.window.onDidChangeActiveTextEditor( (ed) => {ed.setDecorations(....)} )

@yg-i
Copy link

yg-i commented Jun 8, 2024

Also, I noticed that vscode's own inlay parameter hints (which I've read are also implemented using decorations) do persist across active editor change, and are unaffected by the 500ms delay. See this gif demonstration and notice how the 'num' inlay parameter hint in the func() call persists across editor changes.

2024_0608_0310_06 (Extraneous Vole)

Is there a way for extension developers to simulate the effect of persistent decorations?

@1nVitr0
Copy link

1nVitr0 commented Sep 9, 2024

A persistent property would be great. I use decorations to hide tokens and passwords in the Censitive Extension, and have always been annoyed by the delay (see 1nVitr0/plugin-vscode-censitive#50). I have restrained myself from opening an issue as hiding the document's contents until all decorations are ready just doesn't make sense. But being able to make certain decorations persistent would at least remove the delay when switching between already opened editors.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
editor-api Issues about the API of vscode in the area of editors feature-request Request for new features or functionality
Projects
None yet
Development

No branches or pull requests

5 participants
@memeplex @alexdima @1nVitr0 @yg-i and others