Now that we have references code lenses for TS in the January release I'd like to raise an issue with the pretty cool CodeLense animation. Currently it fades in every time it comes into view. This quickly gets distracting and hence annyoing when you navigate a lot in your files.
My request is therefor: either make the animation entirely configurable or show it only on first display of a codelense.
@mike-lischke This animation exists because we resolve the codelens values lazily, when they first enter the editor view. The alternative would be to have them just appear. We also try to reuse the codelenses where possible but do have to recalculate them when switching between files.
@jrieken For this description, it does not sound TypeScript specific. I'm closing this as by design. Please reopen if you think there is a bug here or if the animation should be tweaked
Thanks
I think you closed that too easily here. What's wrong with letting the codelenses just appear? Add an option to let us switch the animation then, if you believe it is not worth to have a flag for each document that signals: animation-shown-once and does not show the animation when this flag is set.
Such things make the difference between great and excellent software.
@jrieken can speak to the intention better, but the 0.5s fade-in makes the view update less jarring. A setting to disable the codelens animation seems to fine grained to me, unless we have lots of people that really want this. If we do anything here, my vote would be to reduce the animation duration
@mike-lischke Are you saying whenever a code move in, out, and back in to the view port in animates? That's not what I am seeing. Can you attach a animated gif or a more precise sample?
Well, I see it when I switch editors, not when I scroll around. Though I'm quite sure that was worse before and the animation also happended when I scrolled. Still, even when switching editors and code jumps around (it's not only the animation, but also the empty lines that get inserted to make room for the codelenses) it becomes quickly annoying:
That's indeed the design. Code lenses are only shown for visible editors, otherwise we would have to manage potentially hundreds of them. Implementation wise, it actually only is one editor which we bind to a different model when selecting tabs.
We can experiment with caching the last n (n < 10) lens-model-pairs but we always have to ask again when the editor gets a different model. Ideally, the lenses stay stable when this happens but there no guarantee.
@jrieken The problem is not that you have to ask again and you should cache the codelense model anyway, in order to be able to quickly update only parts that actually changed (not always the entire editor, what do you think happens with several thousand codelenses otherwise?).
Just disable the animations after a document was shown once. Visually there is no need for any change for codelenses when you switch editors, unless you got differences to the previous set of codelenses. In that case you would only update the display of the changed codelenses, of course. It's quite a waste of resources to update the full document every time you switch tabs.
In fact, now that we have the ability to signal code lense changes by an extension, you can probably stop using your poll approach on each tab switch and rely on the extension to signal any future change (except for the first appearance). That keeps the entire IDE more responsive.
As @mike-lischke pointed out with his recording, the issue is very visible and frustrating. Remembering the positions of last codelenses in given file should be enough to limit the UI jump that's happening when changing the tabs. The movement of lines of code itself is very distracting. It's actually pretty rare that the lens position will change without directly editing the file, and in those rare cases it would be OK to do a small jump. In all other cases, holding the code stationary until the extension reevaluates would solve the biggest issue.
@jrieken What's wrong with managing hundreds of inactive codelenses when you have to manage thousands of lines of code anyway? We don't have a flash of syntax highlighting visible, and that would be less annoying than spreading the text after a second every time you cmd+tab.
I have to echo what others said here. This behavior is incredibly irritating and distracting. I usually work in multiple files at the same time, so I keep switching back and forth between files. Having Code Lens not be there immediately is not a problem at all. The problem is that the delay until it is finally loading is long enough that my eyes and my mind are already used to the file structure. So the sudden movement that then appears afterwards shifts everything making it very difficult to keep track of what is happening. The fact that the shifting is relative to the current cursor position only makes it more complicated for the mind since the behavior then appears to be very inconsistent, making it hard to just live with it.
I really like Code Lens and I think it鈥檚 very helpful. But the behavior of it in VS Code is currently one of the main reasons that makes me still open the full Visual Studio for all my projects. I understand that the editor is implemented very differently there but the Code Lens behavior is so much better tuned there: The Code Lens state is not only persisted across all open tabs, which means that there is neither line shifting nor a delayed fade-in appearing (the information just stays there), but for newly opened files that do not have Code Lens information yet, the space that Code Lens takes is already preallocated. So it can just slowsly fade in after loading, instead of having to shift around lines. The location where code lens appears has to appear also cannot be that difficult to determine. After all, simple syntax analysis can already identify the blocks where a Code Lens information needs to be displayed.
Maybe we can have the syntax definitions emit some additional information for lines where Code Lens should be displayed. That way, the Code Lens allocation would be up to the syntax highlighter (which is already persisted across tabs/files). So even if there is only a single Code Lens module active at all times (although it shouldn鈥檛 be a problem to have the information available for all open tabs), it could just slot into the already preallocated space.
Preallocating code lense positions will probably not improve the situation much, because determining the positions is almost the same work as getting the full code lens info (parsing, token location determination, the rest is just token symbol lookup). I wouldn't mind an initial jump and fade. I like that little animation actually. However, it shouldn't happen all the time when an editor is activated, that's all.
The experience of a sudden movement on screen is really really bad, while switching between pages due to refreshing the codelens. For that reason, I have to turn off the codelens. Actually I like this feature very much, if there is no such an unbearable experience problem.
Chiming in here, can't we just have the reference text area draw on files with references before they render the code to the user? that would at least stop the jarring jump of the code.
This jumping of code around is really annoying. I have also disabled code lens, even though I like the information it provides.
I have seen other related issues reported, and they are just being closed, without any action from the developers, which is very frustrating. I wish they would act on it.
As you can see above, @jrieken referenced the issue I created about this, not realizing this issue had already been created.
Just wanted to chime in and agree that the key thing I find annoying about this is the vertical movement of the lines of code a short time after opening the file. I would have no problem with the reference counts in the CodeLens annotations having a placeholder value until it finishes loading. I just want some vertical space allocated to code symbols that CodeLens would work with allocated on the editor before the loading starts. That way my code won't move around after I open the file.
I found this impactful enough that I decided to disable CodeLens for now, manually checking references.
I am another user that has disabled code lens because it does not persist the information when switching tabs. In Visual Studio, code lens positions are first resolved lazily and eventually the information is shown once that is calculated. The latter is more work, for example in C# it can quickly work out where the methods are but it takes longer to load the number of references to show. In Visual Studio the code lens tags are persisted while the editor is open so VS Code should do the same at least using a LRU model.
Recommend we rename issue title to use the correct term "CodeLens" to improve issue visibility.
@mike-lischke Nitpick here... The name of the feature is "CodeLens", not "CodeLense".
That flowed out of my hands without passing the brain :-)
np. thanks for updating it. :)
After a lot of frustration with code lenses in Terraform, which are both very useful and very jumpy, I found #23652 which follows up here.
Obviously agreed with this issue here but #23652 was closed-and-locked a bit too fast. I don't know that this fix is enough for projects with lots of different files. And keeping in mind that codelenses are supposed to be usable by all languages, not just TS.
So we're still left with the same problem as in #23652: Code lenses cause code to jump around vertically. If they show up while the user is typing it's even more infuriating. Please consider reopening the other issue and maybe implementing at least an option to have lenses show up without increasing the line size (such as the various mockups @solarsailer gave).
Same here, I turned off CodeLens for Terraform scripts in vscode, because of the line jumping.
I wonder if it's possible for the editor to quickly calculate which lines would need CodeLens annotations placed above them when the file is opened. Preferably, this would happen within a few ms. Then, the window can be opened with the space allocated, and the data in the CodeLens annotations can take all the time in the world to load. When it finishes loading, there would be no jumping effect.
I know this won't be popular opinion, but why not have an option to put it in the same line under a mouse on hover effect? I really like the mockups here: https://github.com/Microsoft/vscode/issues/23652
It's not just about line jumping. I prefer to write comments exactly above the block, but CodeLens hijacking that line.
I think there may be two things being discussed in this issue:
I think 1 is unavailable (there will be a delay while the code lens providers return their data), but I think 2 is totally needless (or at least, way slower than it needs to be). The text fade-in can't begin until the text is known, and presumably that's once the code lens command is resolved (in my case, they're always resolved from the start) and therefore seems unnecessary except to avoid text "appearing". If that's the case, why can't the animation just be made twice the speed? And if the code lens is already resolve dbefore it's scrolled on (as in my case), no fade is required at all - it can be rendered before it even scrolls into view.
I don't know about the others commenting here, but for me, it's the slow fade that's irritating, not a delay in the spaces appearing between the lines.
What if CodeLens was its own vertical column to the right of line number or something? Then it can load lazily and when it's available a highlighted number appears showing the number of references - no vertical jump. It's currently duplicating the word "Reference" on every line with "X References". Just make a "References" column similar to line numbers. Better yet, make the line number itself a hover-able, clickable link that loads lazily! :) Just some ideas, this was too annoying for me and I had to turn off CodeLens as well.
Im glad I came here first rather than spending too long trying to figure out how to disable the animation of these.
Is there any update on this matter? Is this something that is likely to happen or not?
Hard to imagine that this flickery rendering behavior is as intended. That is just horrible UX. Luckily CodeLens can be disabled.
@oliversalzburg Unfortunately I need this turned on for my Go projects in order to run the individual tests. You start tests or debug them by clicking these annotations. I really wish they would fix this. I admit I'm not the developers so I don't know all the details, but I feel like the solution could be as easy as allocating the vertical space on the page before the page is opened instead of after the CodeLens data finishes loading.
@welkie Not just Go - in Node and .NET there are many extensions that rely on those annotations. They are very useful, so disabling codelens is not an option. But keeping it drives me mad. Needs to be fixed.
I will push a fix which keeps the code lens for the last 10-15 items around. That will make this much better (less annoying).
@jrieken why does it have to take so long to fade them in? VS Code already knows where they are because the spaces appear very quickly - but then it takes an age for those empty spaces to be populated/fade in.
@jrieken That looks like a pretty drastic improvement already. Appreciate it. Would be nice to have the 15 configurable though to see how high I can go.
VS Code already knows where they are because the spaces appear very quickly - but then it takes an age for those empty spaces to be populated/fade in
@DanTup Didn't you also implement the code lens provider API? The contract is that a provider can quickly provide 'empty' code lenses so that the editor can reserve space and that in a second step lenses, that are in the view port, are resolved. TypeScript makes use of this contract and that's why it takes a bit on first show
I did, but I don't use resolve and it still feels slow for them to fade in (specifically the time between the gaps appearing, and the text being fully visible).
My conversion to gif seems to have slowed it down - it's not quite as bad as it seems there, but it still feels like it could fade much faster and feel snappier.
@jrieken Thank you 1000x. I feel like this will make my development experience so much better with just that improvement.
@DanTup I agree the fade in is distracting. First thing I do when I install an OS or program is disable as many animations as I can. I prefer things to just pop. If the devs have time to provide a way to customize it and disable the fade in, that would make this even better.
Hm... The animation is set to run for .5 seconds: https://github.com/Microsoft/vscode/blob/98ea8943d15564a7665fb131c638a6008e550e6e/src/vs/editor/contrib/codelens/codelensWidget.css#L39-L46
Not sure why that value was chosen but we can certainly make it faster. @aeschli? Suggestions? 100ms?
I presume the animation is just to avoid it "appearing" so as long as it's long enough to not look jarring, the shorter the better. 100ms sounds like a good number if it still appears to fade. If it looks too fast, I think even 200ms would be a decent improvement 馃憤
This is how it runs with 100ms and ease-out-timing. I personally think that the difference is small. I think what makes this appear as "slow" is that we debounce "code-lens-becomes-visible" events by 500ms so that fast scrolling doesn't resolve all lenses. I will also tweak that value
I like how every other line jumping around the screen is apparently considered perfectly acceptable, but the fade-in period needs to be tweaked perfectly so it isn't too distracting...
@oliversalzburg I am listening. What is your suggestion?
@oliversalzburg I think everyone has different things they consider distracting. That's why some people are complaining about lines jumping and some people are complaining about fading in time. I'm glad to see both issues addressed.
@jrieken I think your proposed solution of caching 10-15 CodeLens lines will help a lot, especially if the number cached is configurable in the settings so that people can opt in to getting rid of the jumping effect at the cost of whatever side effects caching many will have.
I think what makes this appear as "slow" is that we debounce "code-lens-becomes-visible" events by 500ms so that fast scrolling doesn't resolve all lenses.
Does this happen for code lenses that don't use resolve too?
I like how every other line jumping around the screen is apparently considered perfectly acceptable
I think it's unavoidable more than acceptable. When you open a file you want the text immediately but computing code lenses can be slow. I don't think anyone would prefer a blank editor while code lenses are fetching from an out-of-process language server.
My gripe was that once the data was available, it still took a long time to be fully visible to the user. This seemed avoidable :)
@jrieken While I much appreciate the new approach you took to avoid too much animation, I'm afraid that won't cut it. What happens when you scroll around and touch more than the cached number of code lenses? It will probably start jumping again. My request was to avoid the animation altogether (after the initial show) and cache all code lenses for an open file.
On the other hand I don't know how many items you keep around. If you, say, keep the last 10000, we are good probably :-D
A word about animation duration: I can't past a concrete link atm. but I know Apple docs and other sources talk about at most 250ms for an animation to appear smooth but unobtrusive. However, here we have apparently a different issue, due to the space created for the new code lenses and their resolution. If possible the space should be reserved after the resolution step to make jumping and animation as short as possible.
If possible the space should be reserved after the resolution step to make jumping and animation as short as possible.
IMO this will make things worse. You'd be increasing the time between opening the file and the lines jumping around, which increases the chances that you're trying to read some code when the spaces appear. The slow fade is annoying, but having text you're reading move is even worse.
cache all code lenses for an open file
That sounds sensible to me. They could still be fetched when you switch to a doc and updated, but if there are no changes it means the space would be reserved on the initial rendering. Ofc, I don't know if the implications of this, especially given the somewhat fuzzy definition of "an open file" :)
I agree, it would be nice for the animation duration to be configurable. Because then I could set it to 0
.
I wish that file is already opened with gaps, so I do not see any jumping. And this gaps must be filled with some lightweight placeholders like "Codelens loading...", so I don't want to format my code everytime, to delete this gaps.
touch more than the cached number of code lenses? It will probably start jumping again. My request was to avoid the animation altogether (after the initial show) and cache all code lenses for an open file.
Just to clarify: This is all code lenses of a file, so we cache for 15 files, not just 15 lenses
I wish that file is already opened with gaps, so I do not see any jumping
@xiety VS Code doesn't know where the gaps should go until the extension/language server provides that information and that could take hundreds of milliseconds or even seconds to return. Delaying rendering any text until all the code lens info is returned would suck. The API allows for "resolving" code lens so the server can provide ranges as fast as possible then fill in the contents as they're scrolled into view, but it's still at the mercy of how fast extensions can respond (and with the best will in the world, it's not going to be as fast as VS Code is ready to render the text on the screen).
This is all code lenses of a file, so we cache for 15 files, not just 15 lenses
Of course, that doesn't sound so bad now :-)
@jrieken
Just to clarify: This is all code lenses of a file, so we cache for 15 files, not just 15 lenses
Thanks, that sounds very reasonable. If we technically cannot reserve the space for code lenses earlier, then not throwing away the already calculated information for open files seems to be a very good compromise.
15 files is probably a very safe number to ensure that most projects will be just fine. Thank you very much for this change!
@aeschli Had some good ideas. Between reloads we now persist on what lines code lens was showing. The theory is that code lenses are likely showing on the same lines again - running a simple document-check first.
Now there is
I am happy this is being addressed. Any idea of when this might be released?
@giggio it has shipped in latest insiders: http://code.visualstudio.com/insiders/ and will ship with the 1.34 stable release
@jrieken I suggest an alternative GUI for it: add a new column next to line numbers and show counts there. This way line heights will remain unchanged
I feel that 16/9 screen are becoming more common than 4/3 or 5/4 screen these days. Why not to use extra screen width that now comes for free?
@baybal We were trying so hard to fix this long-standing problem that we ignored the simpler/better approach... Great idea dude!
@baybal feedback is always welcome but please create a new issue instead of commenting and old/closed/off-topic issues
The changes in the latest release are looking really good 馃憣 Much better UX. Thanks
Most helpful comment
As @mike-lischke pointed out with his recording, the issue is very visible and frustrating. Remembering the positions of last codelenses in given file should be enough to limit the UI jump that's happening when changing the tabs. The movement of lines of code itself is very distracting. It's actually pretty rare that the lens position will change without directly editing the file, and in those rare cases it would be OK to do a small jump. In all other cases, holding the code stationary until the extension reevaluates would solve the biggest issue.
@jrieken What's wrong with managing hundreds of inactive codelenses when you have to manage thousands of lines of code anyway? We don't have a flash of syntax highlighting visible, and that would be less annoying than spreading the text after a second every time you cmd+tab.