Skip to content

Performance: Load Only Necessary Modules On setup and requiring API #3231

@alex-courtis

Description

@alex-courtis

User requiring api.lua or executing setup results in most modules being required. This has a cost ~7-11ms.

See #3229 for background and timing experiments.

Only the following are absolutely required when executing setup for the first time:

008.600  000.064  000.064: require('nvim-tree.log')
008.825  000.224  000.224: require('nvim-tree.utils')
010.094  000.060  000.060: require('nvim-tree.notify')
010.097  000.147  000.087: require('nvim-tree.legacy')
012.854  000.063  000.063: require('nvim-tree.commands')

api.lua does not need to contain any requires barring notify; they can be lazily evaluated on calling the API.

This is long overdue and will greatly ease #2908

Implementation Plan

  • 1 - nvim-tree.lua Move all functions that do not relate to setup into another module. This is not API so we may refactor at will.
  • 2 - Make all api.lua requires minimal and lazy. This is a messy and undesirable solution.
    • For pre-setup it has been addressed by Documentation: API luals Annotations And Help #3088
    • Post setup requires more work. There are 3 categories:
      1. Directly wired to function e.g. api.tree.collapse_all = actions.tree.collapse.all
      2. (no action needed) Explorer wrapped are already lazy e.g. api.fs.clear_clipboard = wrap_explorer_member("clipboard", "clear_clipboard")
      3. Wired to a function returned by the module, called at setup time with arguments e.g. api.fs.rename_full = wrap_node(actions.fs.rename_file.fn(":p"))
    • wrap_node and wrap_node_or_nil should not require any changes
    • c returned functions add unnecessary complexity with little value so should be refactored into directly wired functions
  • 3 - Create a new config module that contains user setup config, set during setup. This will allow us to remove the setup calls for non-class modules; they can require and read from the configuration module.
  • 4 - Remove M.setup call, retrieving config from the new module
    • actions/fs
    • actions/node
    • actions/root
    • actions/tree
    • buffers.lua
    • diagnostics.lua
    • explorer/watch.lua
    • git/utils.lua
    • help.lua
    • keymap.lua
    • lib.lua
    • notify.lua
    • renderer/components
    • view.lua
    • watcher.lua

4 should be executed in separate PRs as there is a large blast radius. 1 should be broken down into small PRs to ameliorate risk and allow fast rollback.

Sub-issues

Metadata

Metadata

Assignees

No one assigned

    Labels

    performanceperformance enhancement

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions