- Watch the video on YouTube!
- Check out the final code on GitHub
- Episode 12 of the Emacs From Scratch series
¶Why is Emacs so slow to start up?
Is it actually slow with no config? Run
emacs -Q to find out!
So why is it so much slower with our configuration?
¶Let’s find out how long it’s taking!
Add a function to
emacs-startup-hook to print out the duration of Emacs startup:
(defun efs/display-startup-time () (message "Emacs loaded in %s with %d garbage collections." (format "%.2f seconds" (float-time (time-subtract after-init-time before-init-time))) gcs-done)) (add-hook 'emacs-startup-hook #'efs/display-startup-time)
All startup behavior is happening in the
A helpful manual page is Summary: Sequence of Actions at Startup.
¶The most important tip: don’t load any packages!
use-package gives you a few different ways to defer package loading:
:hook- Package will be loaded the first time one of the hooks is invoked
:bind- Package will be loaded the first time one of the key bindings is used
:commands- Package will be loaded when one of the commands are used
:mode- Package will be loaded the first time a file with a particular extension is opened
:after- Load this package after other specific packages are loaded
:defer- If you don’t use any of the other options, this one will defer loading until after startup
There are a few other options
use-package provides, but these are all the most likely ones you would use.
The strategy is to look at all of your
use-package expressions and decide whether it really needs to be loaded immediately at startup!
If you want to make sure a package gets loaded at startup despite the use of any of the options above, use
Let’s try it!
"fde" '(lambda () (interactive) (find-file (expand-file-name "~/.emacs.d/Emacs.org")))
¶with-eval-after-load can be useful!
with-eval-after-load is a macro that causes a section of code to be executed only after a particular package gets loaded.
(with-eval-after-load 'org (org-babel-do-load-languages 'org-babel-load-languages '((emacs-lisp . t) (python . t))) (push '("conf-unix" . conf-unix) org-src-lang-modes))
If you need to split up your configuration into multiple sections, this is one way to ensure you don’t accidentally cause a package to load too early!
¶Tweaking the garbage collector
One other common performance trick is to reduce the number of times the garbage collector will run during the startup process.
gc-cons-threshold high at the beginning of your
;; The default is 800 kilobytes. Measured in bytes. (setq gc-cons-threshold (* 50 1000 1000))
Then bring it back down at the end of your
;; Make gc pauses faster by decreasing the threshold. (setq gc-cons-threshold (* 2 1000 1000))
Another option is to use Andrea Corrallo’s gcmh package to manage it automatically.