- Published on
How I Used LLMs to Optimize My Zsh Terminal
I remember the first time I tried optimizing my Zsh configuration. I struggled to find the right search terms to Google it, and then I had to tackle solutions one by one to fix my waterfall of problems.
I faintly remember what I did back then (you don't optimize your terminal every day unless you’ve got persistent configuration issues), but now, with the help of LLMs, this work has become so much easier.
I simply tried this prompt:
My Zsh terminal is slow to start. How can I speed it up?
o1-preview
suggested the following steps:
Steps:
- Edit your
.zshrc
: Add the following lines at the very top and bottom.zmodload zsh/zprof # ... rest of your .zshrc content ... zprof
- Restart your Terminal: Open a new zsh session.
- Analyze the Output: After the session starts, zsh will display a profiling report highlighting which scripts or functions take the most time.
Here are my zprof
results:
num calls time self name
-----------------------------------------------------------------------------------
1) 1 1782.37 1782.37 90.52% 1102.62 1102.62 56.00% nvm_auto
2) 2 609.95 304.98 30.98% 355.18 177.59 18.04% nvm
3) 1 209.67 209.67 10.65% 173.91 173.91 8.83% nvm_ensure_version_installed
4) 1 74.11 74.11 3.76% 74.11 74.11 3.76% handle_completion_insecurities
5) 1 43.67 43.67 2.22% 42.49 42.49 2.16% nvm_die_on_prefix
6) 1 35.75 35.75 1.82% 35.75 35.75 1.82% nvm_is_version_installed
7) 2 32.67 16.33 1.66% 32.67 16.33 1.66% compaudit
8) 2 63.83 31.92 3.24% 31.17 15.58 1.58% compinit
9) 1 69.79 69.79 3.54% 29.20 29.20 1.48% nvm_is_valid_version
10) 1 34.44 34.44 1.75% 23.44 23.44 1.19% nvm_validate_implicit_alias
11) 2 17.89 8.95 0.91% 17.89 8.95 0.91% grep-flag-available
12) 1 11.17 11.17 0.57% 11.04 11.04 0.56% _zsh_highlight_load_highlighters
13) 1 10.95 10.95 0.56% 10.95 10.95 0.56% nvm_echo
14) 1 6.15 6.15 0.31% 6.15 6.15 0.31% nvm_version_greater_than_or_equal_to
15) 5 3.72 0.74 0.19% 3.72 0.74 0.19% is-at-least
16) 6 3.49 0.58 0.18% 3.49 0.58 0.18% is_plugin
17) 1 2.65 2.65 0.13% 2.65 2.65 0.13% colors
18) 1 2.65 2.65 0.13% 2.62 2.62 0.13% _zsh_highlight__function_callable_p
19) 2 2.58 1.29 0.13% 2.58 1.29 0.13% env_default
20) 3 1.96 0.65 0.10% 1.90 0.63 0.10% add-zle-hook-widget
21) 1 1.44 1.44 0.07% 1.44 1.44 0.07% nvm_has
22) 18 1.27 0.07 0.06% 1.27 0.07 0.06% compdef
23) 4 1.18 0.29 0.06% 1.18 0.29 0.06% nvm_npmrc_bad_news_bears
24) 3 1.11 0.37 0.06% 1.11 0.37 0.06% add-zsh-hook
25) 1 0.20 0.20 0.01% 0.20 0.20 0.01% (anon) [/usr/local/share/zsh-autosuggestions/zsh-autosuggestions.zsh:458]
26) 1 0.16 0.16 0.01% 0.07 0.07 0.00% complete
27) 1 0.06 0.06 0.00% 0.06 0.06 0.00% (anon) [/usr/share/zsh/5.9/functions/add-zle-hook-widget:28]
28) 1 11.00 11.00 0.56% 0.05 0.05 0.00% nvm_err
29) 1 0.03 0.03 0.00% 0.03 0.03 0.00% _zsh_highlight__is_function_p
30) 1 0.03 0.03 0.00% 0.03 0.03 0.00% bashcompinit
31) 1 1782.39 1782.39 90.52% 0.03 0.03 0.00% nvm_process_parameters
32) 1 0.01 0.01 0.00% 0.01 0.01 0.00% nvm_is_zsh
33) 1 0.00 0.00 0.00% 0.00 0.00 0.00% _zsh_highlight_bind_widgets
As you can see, nvm
is my main issue. With these results, I started a new chat and asked:
My Zsh terminal is slow to start. How can I speed it up? I have these zprof results:
{zprof results}
The response was clear:
Best Solution: Lazy Loading NVM
To improve your Zsh startup time, the most effective strategy is to lazy load NVM. This means NVM and its functions will only load when you actually need them, such as when you run
node
,npm
, ornvm
commands.Implementation Steps
Remove or Comment Out NVM Initialization in
.zshrc
:Locate and comment out the lines in your
.zshrc
file that initialize NVM:# export NVM_DIR="$HOME/.nvm" # [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
Add Lazy Loading Functions:
Add the following code to your
.zshrc
file to enable lazy loading:lazy_load_nvm() { unset -f nvm node npm npx export NVM_DIR="$HOME/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" --no-use [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" } nvm() { lazy_load_nvm nvm "$@" } node() { lazy_load_nvm node "$@" } npm() { lazy_load_nvm npm "$@" } npx() { lazy_load_nvm npx "$@" }
Explanation:
lazy_load_nvm
Function: Unsets any existing NVM-related functions to prevent conflicts and then sources the NVM script only when needed.- Wrapper Functions: Overwrite the
nvm
,node
,npm
, andnpx
commands to first calllazy_load_nvm
and then execute the actual command.Reload Your Shell:
Apply the changes by restarting your terminal or sourcing your
.zshrc
:source ~/.zshrc
Benefits
- Reduced Startup Time: By deferring NVM initialization, your Zsh shell will start much faster.
- On-Demand Loading: NVM and Node.js tools load only when you need them, conserving resources.
And that's it! My Zsh terminal is now much faster to start.
Final Remarks
People sometimes say that using LLMs is hard or discourage trying it because the few times they tried it didn't work. But like any skill, it sometimes takes a little time to get used to it.
I don't want to mislead anyone here. As you can see, I didn't use any fancy "prompt engineering," but I did use some techniques:
- I asked the same question several times to check if there was anything missing.
- I restarted the chat every time because I wanted a response "as unbiased as possible" from older answers.
- I understood and evaluated all the proposed solutions to see if they were really what I wanted.
And maybe some other tricks, but I do them so naturally that I don't even notice.
It looks like a lot of work, but it was actually very fast. With some practice, you get used to the process, it becomes much easier, and you start to understand the best ways to extract value from any LLM.