Last Updated: February 25, 2016
· bchretien

How to detect plugins slowing Vim down

Vim is all about tweaking your ~/.vimrc and using your own set of plugins to optimize your workflow. However, once in a while, you may end up with some performance issues in Vim, often because you forgot to set some proper plugin parameters.

First, you can analyze Vim's startup process by running Vim with the following command :

$ vim --startuptime 

(cf. this SO answer)

This will generate a simple report with all the scripts that are sourced and the time it takes in milliseconds.

Second, you probably also want to debug some specific actions in Vim (e.g. when switching buffers). For this, you can use Vim's built-in profiling support:

:profile start profile.log
:profile func *
:profile file *
" At this point do slow actions
:profile pause
:noautocmd qall!

(cf. this SO answer)

This will give you an exhaustive report: all the functions that were called, how many times they were called, how much time was spent in each of them etc. This allowed me to detect a huge bottleneck in YouCompleteMe, the culprit being py ycm_state.OnBufferVisit().

count  total (s)   self (s)  function
    1   0.711777   0.710257  <SNR>165_OnBufferVisit()
    1   0.011279   0.000039  <SNR>60_on_window_changed()
    1   0.011201   0.000212  airline#update_statusline()
    2   0.010989   0.000178  <SNR>61_invoke_funcrefs()
    2   0.010571   0.000241  airline#util#exec_funcrefs()
    2   0.009791   0.000228  airline#extensions#default#apply()
    8   0.009306   0.000683  airline#check_mode()
FUNCTION  <SNR>165_OnBufferVisit()
Called 1 time
Total time:   0.711777
 Self time:   0.710257

count  total (s)   self (s)
                              " We need to do this even when we are
                              " not allowed to complete in the current
                              " file because we might be allowed to
                              " complete in the future! The canonical
                              " example is creating a new buffer with
                              " :enew and then setting a filetype.
    1   0.000029   0.000015   call s:SetUpYcmChangedTick()

    1   0.000061   0.000018   if !s:AllowedToCompleteInCurrentFile()

    1   0.000054   0.000015   call s:SetUpCompleteopt()
    1   0.000280   0.000015   call s:SetCompleteFunc()
    1              0.710161   py ycm_state.OnBufferVisit()
    1   0.001182   0.000023   call s:OnFileReadyToParse()

This can also be used to profile the startup process:

$ vim --cmd 'profile start profile.log' \
      --cmd 'profile func *' \
      --cmd 'profile file *' \
      -c 'profdel func *' \
      -c 'profdel file *' \
      -c 'qa!'

Note that Vim needs to be compiled with the appropriate flags. You can check that these options are indeed available by running:

$ vim --version | grep +startuptime >& /dev/null && echo "startuptime available"  || echo "startuptime not available"
$ vim --version | grep +profile >& /dev/null && echo "profile available"  || echo "profile not available"

1 Response
Add your response


Nice collecions of the SO answers, it helps it have a single point of reference :D

One note, others may find useful... turn off syntax highlighting see if that helps.
Not something that seems to show up with the above answers (I probably don't know where to look) but what was slowing me down was scrolling up and down on an html file that had nested javascript.... once I removed the nested javascript my speed was back to normal. I guess having more than one syntax in a single file, slows things done.
Just thought I'd add my 2c.
Happy vim'ing!

over 1 year ago ·