Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.Sign up
fix #21849: Minimap: Show Full Document #74425
But I cannot accept this as is, due to performance issues.
Here are some quick measurements I did for
There's also no throttling of
These times simply blow through our painting time budget.
I think for large files, the approach to render all the lines in a bitmap and then scale it down to the minimap size is not viable.
I will also give more thought to the problem, the current solution "allocates" at minimum 1px per line in the bitmap, which means sometimes we end up with a very high bitmap, like in this case of 30000px which is then scaled down to the screen height of 1000px, and each subsequent update has to pay the cost of recreating this very large bitmap...
I've also tried
The best is to zoom in on a section and see how lines appear/disappear as they presumably line up with the power of two the downscaling uses
In fact, this makes me think that at a certain line - vertical pixel ratio we can render random text in there, since the painted minimap holds no "vertical" correlation whatsoever with the file content... There could be features of the code shape that the minimap captures, such as consistent indentation or a maximum respected line height, or perhaps a tremendously large block comment (100 lines in length or so), but otherwise, we could as well render pixels using Math.random()...
I wonder if sampling would be a better way for rendering such large files...
Yeah I was guessing that the impact for large files is too much, that's why I initially was trying to split up everything in chunks and only update the affected chunks. This way you ended up with almost always changing only one chunk and all the others are just redrawing the images.
There are also a lot of missed opportunities in the current implementation, e.g. the image buffer is always as big as the required size (this is good enough for the old behaviour) but with the whole document visible you end up reallocating on every "Enter"-button press. Which could be easily mitigated. And there are other things as well where the already rendered old data is not reused despite the content is the same (or almost).
But I just wanted to try a minimal "invasive" approach.
Some possible mitigations are just rendering every nth line if the effective line height is below 1px, but I guess this could end up with some weird artifacts. But with >2000 lines things are not visible anyway. At those line counts it would require generating mipmaps (which should be no deal for the GPU, but I don't know how to do it from within such an electron app) and drawing those to prevent this "flickering" appearance.
Another idea is to use a line budged which gets updated every frame, so that huge file changes or the initial update does not hit one frame that much.
I have to check the chrome profiler as well, but I am not familiar with it. (normally I am a c++ guy)
@alexandrudima I have added an undersampling (so it skips lines on large files) this helps a lot, but the tokenizer still takes very long for the whole file at the beginning. But otherwise the undersampling seems to produce a nice stable image data and the performance seems good too. But the decorations are not really visible anymore.
I only render the selection part of the decorations for very large files. The other decorations are barely noticeable anyway at those very tiny effective line heights. And these decorations were the remaining bottleneck on large files.
So overall I am very happy with the results. I don't know if the highlight decorations should be handled different for large files, eg like the scroll bar.
But I can also see that files with millions of lines might still be too slow. But this option adds no real value for those files anyway. So it could fall back to the current behavior at a certain point or just disable it. I would say with such files the whole scrollbar is almost unusable and you navigate by search or something like this anyway.