Zsh function files wait on a shelf while only the called function is loaded into a terminal.

Zsh logo · Photo by Guist · CC BY-SA 4.0 · source

Question: How do I make zsh functions load faster?

2 minzshautoloadzcompilefpathperformancelazy-loadingshelldotfile

Answer

This is actually pretty cool. You can make functions in zsh faster by using the autoload functionality of zsh. With autoload you/zsh doesn’t need to load the full function in memory, it only does so when you call the code. Which makes your startup quicker, because all those functions don’t sit in memory waiting to be called. Just lazy loaded when needed. meep meep

Its rather simple: You place a file in your fpath, I have ~/.zsh/autoload:

zsh
fpath=($HOME/.zsh/autoload $fpath)

My file looks like this:

zsh
$ cat ~/.zsh/autoload/apt-full
apt-update
apt-can-upgrade full || return 0
apt-safe
sudo aptitude full-upgrade
  1. zsh knows about the function:
zsh
$ which apt-full
apt-full () {
  # undefined
  builtin autoload -XUz
}
  1. Only when you call the function it actually loads the code:
zsh
$ which apt-full
apt-full () {
  apt-update
  apt-can-upgrade full || return 0
  apt-safe
  sudo aptitude full-upgrade
}

But you can also do things like this, where you define multiple functions, e.g., main functions and helpers:

zsh
$ cat ~/.zsh/autoload/truncate-directory
truncate_directory() {
  # code here
  foo
}

foo() {
  # some helper function logic here
}

truncate_directory $@

Now, the really cool thing is, you can compile the file and it becomes a .zwc, which is bytecode for zsh and it even reduces the load/execution time of your code. Because zsh doesn’t need to compile it to bytecode, its done already. And zsh is smart, because if it sees the original file is newer, it will use that one instead of the .zwc file. What?! :))

Run zcompile $file and you golden. I’m being meta, and I zcompile my fpath with a zcompiled function:

zsh
xzcompilefpath () {
  local i
  for i in $fpath
  do
    xzcompiledir $i
  done
}

If you want you can have a look at my autoloaded functions, have a look at dotty