DEV Community

TANIGUCHI Masaya
TANIGUCHI Masaya

Posted on

Introduction to the lighting-fast plugin manager, vim-jetpack

GitHub logo tani / vim-jetpack

The lightning-fast plugin manager, alternative to vim-plug

🚀 vim-jetpack

linux macos windows

The lightning-fast minimalist plugin manager for Vim/ Neovim. vim-jetpack is a jetpack for the most of vimmers. Unbelievably, it is faster than vimrc uses the built-in plugin manager only.

jetpack

Features

  • Lightning-fast startup
    • It optimizes the search algorithm for the runtimepath
  • Single file plugin
    • You need to just put the single file to use this software
  • Multiple DSLs (Domain Specific Languages)
    • You can use a favorite notations, which are similar to vim-plug, dein.vim packer.nvim, and paq.nvim
  • Fancy UI (User Interface)
    • You can see a progress of installation with a graphical interface
  • pack/*/start-free architecture
    • Installed plugins do not pollutes your vim until calling jetpack#-functions

Benchmark

In the simple cases, vim-jetpack is the fastest plugin manager.

We measured a startup time 10 times for each plugin managers. The following chart is the result.

Although jetpack is inferior to minpac in terms of minimum value, it has the lowest median…

Introduction

vim-jetpack is a modernized implementation of vim-plug for vim8/neovim, incorporating the optimizations used in dein.vim, and is the fastest and lightest plugin manager with a Packer.nvim-like command set. It is faster than Vim without a plugin manager and with built-in plugin management. In other words, the time saved by the optimization performed by the plugin manager is greater than the overhead of loading the plugin manager.

I can confidently recommend it to anyone using Vim's Plugin Manager, as well as to minimalists who manage their plugins with Vim's built-in functionality.

It is the fastest existing plugin manager

Speed is important. Vim starts up much faster than most text editors, but even so, if you start and stop Vim frequently, the slightest delay can be annoying. vim-jetpack is the fastest. It is fast enough even without setting up delayed loading. This is because vim-jetpack optimizes the directory structure of the plugins in advance when installing plugins, such as dein.vim, to reduce the number of directories to be loaded at startup, thereby reducing the startup time.

The following table and graph show the statistical results of 10 launches of the 6 plugin managers (vim-plug, packer.nvim, dein.vim, vim-jetpack, minpac, packer.nvim, paq.nvim, and vim-plug) with appropriate vimrc settings. The unit is milliseconds.

jetpack_benchmark

dein jetpack minpac packer paq plug
min 80.61 69.93 64.97 75.38 73.92 77.63
max 96.02 74.48 81.30 89.40 84.95 82.82
median 85.26 71.92 72.38 78.38 78.16 80.36
mean 86.24 71.97 72.48 80.07 78.21 80.12
variance 27.09 2.07 23.99 24.56 10.83 3.57

We can immediately see from the graph that minpac and jetpak are clearly running faster than the other four. So let's take a closer look at jetpack and minpac using the table.

minpac has a smaller minimum value and a faster startup record than jetpack, but its maximum value is also (edited: I delete the word 'significantly') higher. minpac's maximum value is slower than the average of all three startups (packer, paq, and vim-plug), and its range of maximum and minimum values is large, with the second largest variance after dein. The variance of the maximum and minimum values is the second largest after dein. Thus, while it may start up faster, its startup speed is not stable, and it is not always fast.

Although the minimum value of jetpack is lower than that of minpac, its median and average values are both lower than those of any other plugin manager. Even more noteworthy is the very small variance of jetpack's records. vim-plug's variance is small enough, but jetpack's variance is by far the smallest. jetpack has the smallest variance, mean, and median among the six plugin managers, which reads that it is stable and always starts up fast.

Practically, you might use amount of plugins more than I tested. Then, we expect reducing 40 ~ 100 ms for the startup.
The tested vimrc is available on our repository.

Graphical installation progress

jetpack

When the plugin manager is described as fast, it is not just about execution speed. It is important that the user experience is fast without being stressful. In this respect, the recent lightweight plugin managers have been frustrating for me. After hitting the command to install a package, all I was presented with was a blunt message, making it difficult to predict when the installation would complete, and I felt that the experience was slow regardless of the actual execution speed.

vim-jetpack solves this problem by providing a vim-plug-like progress bar. This allows users to predict how much work is currently in progress and when it will be completed, improving the experience.

Highly compatible with Vim-plug

Most software can achieve speedups by reducing features. However, vim-jetpack makes an effort to provide options comparable to vim-plug. Most vim-plug users can simply run :s/plug/pack/g | s/Plug/Pack/g to complete the migration to vim-jetpack. If a simple string substitution is all it takes to speed things up, there's no reason not to make the transition!

vim-jetpack is almost compatible with vim-plug.

name type description
branch/ tag/ commit sring Branch/ tag/ commit of the repository to use
rtp string Subdirectory that contains Vim plugin
dir string Custom directory for the plugin
as string Use different name for plugin
do string or func Post-update hook
on string or list On-demand loading: Commands, <Plug>, Events
for string or list On-demand loading: File types
frozen boolean Do not update

Additionally, vim-jetpack provides Vim 8/ Neovim packages interface.

name type description
opt boolean On-demand loading: packadd {name}

Multiple DSLs can be used.

Many people who use Vim are probably particular. Some prefer a DSL like vim-plug, some prefer a minimal DSL with Vimscript functions like dein.vim, some prefer a Lua configuration like packer.nvim, and some prefer a configuration like paq.nvim. vim-jetpack supports all these writing styles.

vim-plug style

call pack#begin()
Pack 'junegunn/fzf.vim'
Pack 'junegunn/fzf', { 'do': {-> fzf#install()}
Pack 'neoclide/coc.nvim', { 'branch': 'release' }
Pack 'neoclide/coc.nvim', { 'branch': 'master', 'do': 'yarn install --frozen-lockfile' }
Pack 'vlime/vlime', { 'rtp': 'vim' }
Pack 'dracula/vim', { 'as': 'dracula' }
Pack 'tpope/vim-fireplace', { 'for': 'clojure' }
call pack#end()
Enter fullscreen mode Exit fullscreen mode

dein/ minpac style

call pack#begin()
call pack#add('junegunn/fzf.vim')
call pack#add('junegunn/fzf', { 'do': {-> fzf#install()} })
call pack#add('neoclide/coc.nvim', { 'branch': 'release' })
call pack#add('neoclide/coc.nvim', { 'branch': 'master', 'do': 'yarn install --frozen-lockfile' })
call pack#add('vlime/vlime', { 'rtp': 'vim' })
call pack#add('dracula/vim', { 'as': 'dracula' })
call pack#add('tpope/vim-fireplace', { 'for': 'clojure' })
call pack#end()
Enter fullscreen mode Exit fullscreen mode

packer style

require('pack').startup(function(use)
  use 'junegunn/fzf.vim'
  use {'junegunn/fzf', run = 'call fzf#install()' }
  use {'neoclide/coc.nvim', branch = 'release'}
  use {'neoclide/coc.nvim', branch = 'master', run = 'yarn install --frozen-lockfile'}
  use {'vlime/vlime', rtp = 'vim' }
  use {'dracula/vim', as = 'dracula' }
  use {'tpope/vim-fireplace', ft = 'clojure' }
end)
Enter fullscreen mode Exit fullscreen mode

paq style

require('pack').setup {
  'junegunn/fzf.vim',
  {'junegunn/fzf', run = 'call fzf#install()' }
  {'neoclide/coc.nvim', branch = 'release'}
  {'neoclide/coc.nvim', branch = 'master', run = 'yarn install --frozen-lockfile'}
  {'vlime/vlime', rtp = 'vim'}
  {'dracula/vim', as = 'dracula'}
  {'tpope/vim-fireplace', ft = 'clojure' }
}
Enter fullscreen mode Exit fullscreen mode

Lightweight and easy to install

The beauty of vim-plug is that the package manager itself consists of only one file. This makes it possible to deploy vim-plug in any environment where we can fetch files using HTTP requests. vim-jetpack follows suit, and is contained in a single file. Because of its small size, vim-jetpack can be included in the repository as one of the Vim configuration files.
As a side note, Vimscript uses classic sequential interpreter processing, so the small size of the code simply improves the speed.

Vim

curl -fLo ~/.vim/autoload/pack.vim --create-dirs https://raw.githubusercontent.com/tani/jetpack/master/autoload/jetpack.vim
Enter fullscreen mode Exit fullscreen mode

Neovim

curl -fLo ~/.config/nvim/autoload/pack.vim --create-dirs https://raw.githubusercontent.com/tani/jetpack/master/autoload/jetpack.vim
Enter fullscreen mode Exit fullscreen mode

Bootstrapping

Also, like vim-plug, it consists of a single file, so it is possible to write a bootstrap process to automatically install it.

let data_dir = has('nvim') ? stdpath('data') . '/site' : '~/.vim'
if empty(glob(data_dir . '/autoload/pack.vim'))
  silent execute '!curl -fLo '.data_dir.'/autoload/jetpack.vim --create-dirs  https://raw.githubusercontent.com/tani/vim-jetpack/master/autoload/jetpack.vim'
  autocmd VimEnter * JetpackSync | source $MYVIMRC
endif
Enter fullscreen mode Exit fullscreen mode

Easy to configure and operate

If you are just using a plugin, installing and updating plugins at the same time is often not problematic. Therefore, vim-jetpack allows you to install, update, and optimize all at once with only a single command JetpackSync. Users can keep their configuration files up-to-date with JetpackSync (or just J, depending on your environment).

There are two optimization levels in vim-jetpack, which can be adjusted with g:pack#optimization. The let g:pack#optimization=0 disables any optimization. This is the same behavior as vim-plug. With let g:pack#optimization=1, optimization is performed only when it is safe to do so. This is the default behavior of vim-jetpack.

Is it faster than dein.vim?

If you are knowledgeable about Vimscript and can carefully configure vimrc, dein.vim is still the fastest.

If you know when Vim events are fired, if autoloading is required, and if the dependencies and loading order between plugins are well maintained, you can use more advanced delay processing to minimize the number of plugins loaded at startup.

On the other hand, dein.vim does a lot of processing at startup to provide advanced customization features. If the user simply wants to write and load a Vim plugin, most of what is being done at this time is wasted runtime.

vim-jetpack cuts out a lot of that wasted processing by reducing the customizable features to the equivalent of a vim-plug. This allows it to run faster than dein.vim.

Conclusion

vim-jetpack is the fastest and lightest plugin manager. In most cases, simply migrating to it will greatly reduce startup time, and unless you like the fancy interface of vim-plug, there is no reason not to migrate. vim-jetpack accelerates your vim.

Top comments (4)

Collapse
 
moopet profile image
Ben Sinclair

minpac has a smaller minimum value and a faster startup record than jetpack, but its maximum value is also significantly higher

I'd challenge your use of the word "significantly" there, and everywhere else - is 10ms something a human can notice during the startup of an application?

Even if I opened Vim 1000 times a day, I'd save ten seconds.

Collapse
 
tani profile image
TANIGUCHI Masaya

Good point.
I might oversate the performance. However, we can see the same word choice in introduction to filetype.lua in neovim.

Well, creating thousands of autocommands on startup is not exactly very performant. Indeed, filetype.vim is one of the slowest (perhaps the slowest) startup files shipped with Neovim. (...)
This is the approach filetype.lua takes, which means that it is considerably more performant than filetype.vim.
reddit.com/r/neovim/comments/rvwsl...

In my environment, filetype.vim takes around 10ms.

We may feel a delay if it takes 33ms (i.e., 1 frame for 30 fps).
It is valuable to reduce 10ms, isn't it?

Collapse
 
moopet profile image
Ben Sinclair

I think at the point where we're measuring 1-off improvements in tens of milliseconds, it's not valuable. If this was in a library being called hundreds of times, then sure. Otherwise, it's only valuable so long as it doesn't impact anything else, such as code readability or cross-platform compatibility. I mean, for example, if you get an optimisation for one platform by splitting the code, for example, then it's debatable whether you've improved the final product.

Collapse
 
pandademic profile image
Pandademic • Edited

wow! Thank you for creating this!