echasnovski / mini.nvim

Library of 40+ independent Lua modules improving overall Neovim (version 0.8 and higher) experience with minimal effort
MIT License
5.4k stars 191 forks source link

mini.animate scroll is very slow for vertically long files. #1374

Closed 231tr0n closed 1 day ago

231tr0n commented 1 day ago

Contributing guidelines

Module(s)

mini.animate

Description

Pressing gg to go to top of the file and pressing G to go to bottom of file when scrolling animation is enabled is not smooth. It lags on big files and the ui stutters.

Neovim version

v0.11.0-dev-1261+gab9cfc4dc3

Steps to reproduce

vim.env.LAZY_STDPATH = ".repro"
load(vim.fn.system("curl -s https://raw.githubusercontent.com/folke/lazy.nvim/main/bootstrap.lua"))()
require("lazy.minit").repro({
    spec = {
        "echasnovski/mini.animate",
    },
})

vim.o.mousescroll = "ver:1,hor:1"
require("mini.animate").setup()

Please rename this file to sqlite3.c since github is not allowing me to upload files with .c extension sqlite3.c.txt

nvim -u repro.lua sqlite3.c

Expected behavior

Scroll smoothly

Actual behavior

Not scrolling smoothly

231tr0n commented 1 day ago

On a side note, I do think the file sqlite.c is quite big and since a lot of calculations are done probably to get the scrolling effect it is slow. But I just wanted to raise this defect to bring this issue under your radar and see if you could make some performance optimizations to make this work properly.

231tr0n commented 1 day ago

Also one last thing, for bug reproduction, I think it should be possible to create a minimal repro script with mini.deps afaik. Do you think something like the lazy minimal repro but with mini.deps could be added to the bug report template file if you think it is fine?

echasnovski commented 1 day ago

Thanks for the issue!

I can reproduce, but with some caveat: there is a smooth animation (at least) if it is the first scroll of the entire Neovim session. Later it is done in kind of two-step. Here is a demo of G and later gg:

https://github.com/user-attachments/assets/f4ce2f76-5a62-4798-a72f-055502f29460

Do you have the same experience?

Adding vim.cmd('redraw') in various places helps almost entirely, but not sure this is a good idea for performance reasons.

231tr0n commented 1 day ago

Thanks for the issue!

I can reproduce, but with some caveat: there is a smooth animation (at least) if it is the first scroll of the entire Neovim session. Later it is done in kind of two-step. Here is a demo of G and later gg: mini-animate_scroll-bigfile-lag.mp4

Do you have the same experience?

For me it gets stuck while going up and down both. Basically there is no scrolling effect anymore. That is the main issue.

echasnovski commented 1 day ago

For me it gets stuck while going up and down both. Basically there is no scrolling effect anymore. That is the main issue.

That's not what I described. I also have it both up and down but only after the first valid animation.

231tr0n commented 1 day ago

For me it gets stuck while going up and down both. Basically there is no scrolling effect anymore. That is the main issue.

That's not what I described. I also have it both up and down but only after the first valid animation.

Ohh ok my bad yeah.

231tr0n commented 1 day ago

You are right the first animation is going correct. From then it stutters for both up and down motions. I can confirm.

echasnovski commented 1 day ago

This should now be fixed on latest main.

The issue was not in scrolling per se, but the fact that its drawing was (somehow) blocked by cursor animation. I noticed it because disabling cursor animation made things work. "Works on first scroll" was also an indicator of this as cursor animation is not done on first move.

This problem in this issue manifested itself because cursor animation was done on every line between start and end positions. As each step was about 0.00096 milliseconds on 260000 line jump and timers not working on sub-millisecond delay there were a lot of steps (about 1040) which were done "immediately". As each step is "delete extmark and add extmark", this somehow resulted into blocking the scroll redraw.

The solution here is to limit the number of steps in cursor animation. This is technically breaking, but nothing serious should be visible on user side (hopefully).

231tr0n commented 1 day ago

As always awesome work. One last thing @echasnovski how much time more till mini.snippets release.

echasnovski commented 1 day ago

As always awesome work. One last thing @echasnovski how much time more till mini.snippets release.

I don't know. I have settled on design and the code is mostly working. Right now I am extensively beta-testing with daily usage. Testing and documentations remains. I am hopeful to release this month.