How can I make Emacs start-up faster?
Others have covered using gnuserve
and emacsclient
, and I'd suggest compiling within emacs (being able to jump to compilation errors is a win).
But, specifically speeding up the .emacs can be done by:
Byte compiling the .emacs file, which you can do automatically by using this snippet of code
Replacing as many of the
(require 'package)
statements with autoloaded functionality. This will delay loading of lisp until it's actually required. Using this technique allowed me to speed up my startup from >6 seconds to <1. This takes a little bit of work because not all libraries come properly markedautoload
.Removing code/functionality you no longer use.
Try running emacs with the option
--no-site-file
to avoid loading unnecessary packages in the site installationsite-start.el
.If you are really serious, you can roll your own emacs with your favorite functionality already loaded. This, of course, means it's more involved to make changes to what you have in your
.emacs
because it's a part of the binary. Follow the link for information on how to usedump-emacs
.Buy a faster computer and/or faster disk.
How to determine what your .emacs loads
Now, how do you find out what your .emacs loads? With the goal to remove the functionality, or to delay it? Check your *Messages*
buffer, which contains lines like:
Loading /home/tjackson/.emacs.tjackson.el (source)... Loading /home/tjackson/installed/emacs/lisp/loaddefs.el (source)...done Loading /user/tjackson/.elisp/source/loaddefs.el (source)...done Loading autorevert...done Loading /home/tjackson/.emacs.tjackson.el (source)...done
If you'll notice, the Loading
statements can nest: the first .emacs.tjackson.el
ends with ...
and the last line shows the .emacs.tjackson.el
load is ...done
. All those other files are loaded from inside my .emacs.tjackson.el
file. All the other loads are atomic.
Note: If you have a large .emacs, it's possible that the *Messages*
buffer will lose some of the messages because it only keeps a fixed amount of information. You can add this setting early on to your .emacs
to keep all the messages around:
(setq message-log-max t)
Note: It the 'load
command will suppress the messages if its fourth argument nomessage
is non-nil, so remove any such invocations (or, advise 'load
and force the fourth argument to be nil
).
A couple of tips:
Use autoloads
Using autoload saves you from loading libraries until you use them. For example:
(if (locate-library "ediff-trees") (autoload 'ediff-trees "ediff-trees" "Start an tree ediff" t))
Compile your .emacs
Gives you a slight speed increase although there are pitfalls if you work with version control and your .emacs is newer than .emacs.elc. One common trick is:
(defun autocompile nil "compile itself if ~/.emacs" (interactive) (require 'bytecomp) (let ((dotemacs (file-truename user-init-file))) (if (string= (buffer-file-name) (file-chase-links dotemacs)) (byte-compile-file dotemacs)))) (add-hook 'after-save-hook 'autocompile)
Learn to love emacs server.
Running emacs as a server means never having to close it down. However I note your still using emacs22. emacs23 supports multi-tty which makes it a lot easier to run emacs in one screen session and then bring up new windows in another terminal. I use emacs to edit mail for my mail client (mutt) and emacsclient is fantastic for these sort of quick edits.
Don't close Emacs every time you want to use the shell. Use Ctrl-Z to move Emacs to the background and the fg
command in Bash to move it back to the foreground.
In addition to Adam Rosenfield's solution, I recommend to use Emacs in server mode. You may add (server-start)
to your dotemacs, and run emacsclient
instead of emacs
whenever you want to open file in Emacs. That way you have to pay the loading cost of Emacs only once, after then clients pop up immediately.
Edit
You're right, v22 does not create a new frame. Create a shell script that do the trick:
#!/bin/bash
# Argument: filename to open in new Emacs frame
/usr/bin/emacsclient -e '(let ((default-directory "`pwd`/")) (select-frame (make-frame)) (find-file "'$1'"))'
Edit 2
In v24+, you can do emacsclient -c
to create a new frame.