Is it actually slow with no config? Run emacs -Q
to find out!
So why is it so much slower with our configuration?
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 normal-top-level
function!
A helpful manual page is Summary: Sequence of Actions at Startup.
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 :demand t
.
Let’s try it!
"fde" '(lambda () (interactive) (find-file (expand-file-name "~/.emacs.d/Emacs.org")))))
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!
One other common performance trick is to reduce the number of times the garbage collector will run during the startup process.
Set the gc-cons-threshold
high at the beginning of your init.el
:
;; 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 init.el
:
;; Make gc pauses faster by decreasing the threshold.
(setq gc-cons-threshold (* 2 1000 1000))
Another option is to use this package: https://gitlab.com/koral/gcmh/