[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Optimizing startup speed

From: Philipp Haselwarter
Subject: Re: Optimizing startup speed
Date: Fri, 04 Nov 2011 01:04:04 +0100
User-agent: Gnus/5.110018 (No Gnus v0.18) Emacs/24.0.91 (gnu/linux)

Actually `require' /does/ load the whole file as soon as
(require 'library) is evaluated. Many packages for emacs suggest to just
`require' them in your .emacs, but this is not a very good idea, as it
loads on startup (pulling in dependencies etc).
For example if you just want to read your mail with gnus, you don't need
to lose your time loading libraries for dealing with java code.

Most packages have some kind of entry point (except ofc things like
global minor modes that you really always want to be active).
Ideally the package comes with a 'package-loads.el' or '-autoloads.el'
which does not contain the actual library code but just the signatures
of these entry points and the name of the file where the actual
definition resides.
Emacs then offers you to use these functions, often as hooks or
commands, and loads the actual code just when it needs (ie when you
first call it).
If the package fails to provide autoloads you can easily define them
yourself. For example if the package « brew.el » contains a command
« brew­arabica », you could put the line
--8<---------------cut here---------------start------------->8---
(autoload 'brew­arabica "brew" "Brews a nice cup of arabica" t)
--8<---------------cut here---------------end--------------->8---
in your config file. Now startup won't be slowed down and the brew
package will be loaded just when you need it.

Factoring out configuration of features/packages also has the advantage
of reducing the quantity of code that has to be evaluated.
For example, if our "brew" package contained a « after­brew­hook »,
there's no point in assigning values to that hook until the package is
loaded. This can be achieved using `eval-after-load':
--8<---------------cut here---------------start------------->8---
(eval-after-load 'brew '(add-hook 'after­brew­hook 'brew­add­sugar))
--8<---------------cut here---------------end--------------->8---

For big packages you can easily wind up with a few hundred lines of
configuration. In those cases you factor it out to a my-brew-config.el
file that you require after « brew » is loaded:

this goes into .emacs:
--8<---------------cut here---------------start------------->8---
(eval-after-load 'brew '(require 'my­brew­config))
--8<---------------cut here---------------end--------------->8---

and this into my-brew-config:
--8<---------------cut here---------------start------------->8---
(add­hook 'after­brew­hook 'brew­add­sugar)
(setq brew­sugar­per­cup 7)
--8<---------------cut here---------------end--------------->8---

Another advantage of organizing your stuff this way is that you can more
easily share (and debug) your configuration by keeping all your personal
data in one separate file (user-full-name, erc-nick, etc).

Once you have all this set up and find starting emacs still too slow you
can use 'C-u M-x byte-recompile-directory' or 'M-x byte-compile-file'
(`B' in dired) to compile additional packages and config files. Just be
careful to recompile after you change something in your config, emacs
will rather load my-brew-config.elc than my-brew-config.el.

I hope this makes things a little clearer :)

Philipp Haselwarter

reply via email to

[Prev in Thread] Current Thread [Next in Thread]