Packer_compiled.lua takes up 57% of startup time

I use startup time and I just realized that packer_compiled.lua takes 57% of the time my neovim takes to load. Is it normal ? What can I change/remove/add ? Thank you & have a good day! (:

local M = {}

function M.config()
    local fn = vim.fn
    local install_path = fn.stdpath("data") .. "/site/pack/packer/start/packer.nvim"

    if fn.empty(fn.glob(install_path)) > 0 then
        fn.system({ "git", "clone", "https://github.com/wbthomason/packer.nvim", install_path })
        vim.api.nvim_command("packadd packer.nvim")
    end

    return require("packer").startup { function(use)

        use {
            "lewis6991/impatient.nvim",
            config = function()
                require('impatient')
            end
        }

        use {
            "LionC/nest.nvim",
            config = function()
                require("mappings").config()
            end
        }

        use "wbthomason/packer.nvim"
        use "nvim-lua/plenary.nvim"
        use "tpope/vim-surround"
        use "wellle/targets.vim"
        use "tpope/vim-sleuth"
        use "farmergreg/vim-lastplace"
        use "ellisonleao/gruvbox.nvim"
        use "fedepujol/move.nvim"
        use "luukvbaal/stabilize.nvim"

        use {
            "romainl/vim-cool",
            event = "cmdlineenter"
        }

        use {
            "nvim-telescope/telescope.nvim",
            config = function()
                require("plugins.telescope").config()
            end,
            requires = {
                {
                    "nvim-telescope/telescope-fzf-native.nvim",
                    run = "make"
                }
            },
            keys = { { "n", "<leader>f" } }
        }

        use {
            "kyazdani42/nvim-tree.lua",
            requires = {
                "kyazdani42/nvim-web-devicons"
            },
            config = function()
                require("plugins.tree").config()
            end,
            cmd = "NvimTreeToggle"
        }

        use {
            "nvim-treesitter/nvim-treesitter",
            event = "BufRead",
            run = "TSUpdate",
            config = function()
                require("plugins.treesitter")
            end,
            requires = {
                {
                    "nvim-treesitter/nvim-treesitter-textobjects",
                    after = "nvim-treesitter"
                },
                {
                    "RRethy/nvim-treesitter-textsubjects",
                    after = "nvim-treesitter"
                }
            }
        }

        use {
            "hrsh7th/nvim-cmp",
            event = "InsertEnter",
            config = function()
                require("plugins.cmp").config()
            end,
            requires = "onsails/lspkind-nvim"
        }

        use { "hrsh7th/cmp-path", after = "nvim-cmp" }
        use { "saadparwaiz1/cmp_luasnip", after = "nvim-cmp" }
        use { "hrsh7th/cmp-buffer", after = "nvim-cmp" }
        use {
            "tzachar/cmp-tabnine",
            run = "./install.sh",
            config = function()
                require('cmp_tabnine.config'):setup({
                    show_prediction_strength = true
                })
            end,
            after = "nvim-cmp"
        }

        use {
            "szw/vim-maximizer",
            cmd = "MaximizerToggle"
        }

        use {
            "L3MON4D3/LuaSnip",
            config = function()
                require("luasnip.loaders.from_snipmate").lazy_load()
            end,
            after = "nvim-cmp"
        }

        use {
            "mhartington/formatter.nvim",
            config = function()
                require("plugins.formatter").config()
            end,
            event = "BufWritePre"
        }

        use {
            "williamboman/nvim-lsp-installer",
            {
                "neovim/nvim-lspconfig",
                config = function()
                    require("plugins.lsp").config()
                end,
                requires = {
                    "hrsh7th/cmp-nvim-lsp"
                }
            }
        }

        use {
            "kkoomen/vim-doge",
            cmd = "DogeGenerate",
            run = function()
                vim.fn["doge#install"]()
            end
        }

        use {
            "folke/zen-mode.nvim",
            cmd = "ZenMode",
            config = function()
                require("zen-mode").setup()
            end
        }

        use {
            "rktjmp/paperplanes.nvim",
            cmd = "PP",
            config = function()
                require("paperplanes").setup({
                    provider = "paste.rs",
                })
            end
        }

        use {
            "xiyaowong/accelerated-jk.nvim",
            config = function()
                require("accelerated-jk").setup()
            end,
            keys = { { "n", "j" }, { "n", "k" } }
        }

        use {
            "sindrets/diffview.nvim",
            cmd = "DiffviewOpen",
            config = function()
                require("diffview").setup {
                    file_panel = {
                        position = "bottom"
                    }
                }
            end
        }

        use {
            "numToStr/Comment.nvim",
            config = function()
                require("Comment").setup({
                    ignore = "^$"
                })
            end,
            requires = {
                {
                    "JoosepAlviste/nvim-ts-context-commentstring",
                    after = "nvim-treesitter"
                }
            }
        }

        use {
            "folke/persistence.nvim",
            event = "BufReadPre",
            config = function()
                require("persistence").setup()
            end
        }

        use {
            "dstein64/vim-startuptime",
            cmd = "StartupTime"
        }

        use {
            "windwp/nvim-autopairs",
            config = function()
                require("nvim-autopairs").setup {}
            end
        }

        use {
            "jaredgorski/spacecamp",
            event = "GUIEnter"
        }

        use {
            "justinmk/vim-sneak",
            keys = {
                { "n", "S" },
                { "n", "s" }
            }
        }

        use {
            "akinsho/toggleterm.nvim",
            config = function()
                require("plugins.term").config()
            end,
            cmd = "ToggleTerm"
        }

        use {
            "cappyzawa/trim.nvim",
            event = "BufWritePre",
            config = function()
                require("trim").setup({})
            end
        }

        use {
            "hoob3rt/lualine.nvim",
            config = function()
                require("plugins.lualine").config()
            end
        }

        use {
            "tpope/vim-fugitive",
            cmd = { "G", "Gdiff" }
        }

        use {
            "alvan/vim-closetag",
            ft = { "html", "php" },
            event = "BufWritePre"
        }

    end
    }
end

return M

Yes, that is to be expected, since everything you put in config is actually executed by packer_compiled.lua during startup – and the reported times are transitive, meaning that everything these required functions do is attributed to it as well.

In a nutshell, since packer_compiled.lua is what actually triggers the code to be run (which looks like most of the things in a normal config), the reported timing is correct.

You’d have to check with your startup plugin whether it’s possible to only report self time (i.e., excluding the time spent running files that are sourced from the given file).

If you use nvim --startuptime profile.log directly, you’ll see that each file has three columns:

  1. elapsed clock time
  2. self+sourced time (what you’re seeing; useful to identify the biggest entry points, which pre-Lua would be individual plugins in your runtimepath)
  3. self time
1 Like

This is exactly correct! However, I also want to point you (@vzytoi) to packer’s built-in profiling functionality, which will give you granular information about what’s costing time during packer_compiled: GitHub - wbthomason/packer.nvim: A use-package inspired plugin manager for Neovim. Uses native packages, supports Luarocks dependencies, written in Lua, allows for expressive config

1 Like

This is really interesting, it seems like it’s vim-lspconfig that takes a long time to load.

                           packer.nvim
 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  Config for nvim-lspconfig took 7.67975ms
  Config for impatient.nvim took 4.484459ms
  Config for Comment.nvim took 1.894958ms
  Config for lualine.nvim took 1.138667ms
  Config for nest.nvim took 0.766625ms
  Config for nvim-autopairs took 0.500333ms
  Defining lazy-load commands took 0.058708ms
  Defining lazy-load keymaps took 0.021375ms
  Defining lazy-load event autocommands took 0.012ms
  Defining lazy-load filetype autocommands took 0.008125ms
  Defining packer_plugins took 0.004416ms
  Luarocks path setup took 0.001791ms
  try_loadstring definition took 0.000125ms

Yes, but that might not be specific to nvim-lspconfig: Much of the Lua API (vim.*, with the exception of vim.api) is β€œlazy-loaded” itself. That means that the first plugin that accesses, say, vim.keymap pays the prize for it in this list, and following plugins get to use it from the cache. So a different load order will show you different timings. (You can force this by removing nvim-lspconfig and see other plugins’ startup times increase.)

Also, you really want to put require'impatient' at the top of your init.lua; otherwise plugins that are used before it will not profit from it. (I believe that is another reason why nvim-lspconfig is an outlier here: it’s not loaded from cache because that isn’t ready yet.)