分析慢的原因
首先下载 benchmark-init 这个插件,
在配置最开始的位置写下配置:
(let (
;; 加载的时候临时增大`gc-cons-threshold'以加速启动速度。
(gc-cons-threshold most-positive-fixnum)
;; 清空避免加载远程文件的时候分析文件。
(file-name-handler-alist nil))
(require 'benchmark-init-modes)
(require 'benchmark-init)
(benchmark-init/activate)
;; 下面才写你的其它配置
)
启动完毕后,执行 M-x benchmark-init/show-durations-tree 命令,这个命令会递归的打印出所有插件的耗时明细。
优化: 动态加载插件
比如下面这个配置会禁止Emacs退出的时候问后台进程是否需要杀掉的问题,会用到 noflet 这个库。
一般你可以这样写:
(require 'noflet)
(defadvice save-buffers-kill-emacs (around no-query-kill-emacs activate)
"Prevent annoying \"Active processes exist\" query when you quit Emacs."
(noflet ((process-list ())) ad-do-it))
这样写的坏处是,Emacs没有退出时不会执行这个advice, 但是一启动就会加载 noflet 这个库, 浪费了启动时间。
优化的方式如下,把要调用的库在用的时候再加载,改成这样就好很多:
(defadvice save-buffers-kill-emacs (around no-query-kill-emacs activate)
"Prevent annoying \"Active processes exist\" query when you quit Emacs."
(require 'noflet)
(noflet ((process-list ())) ad-do-it))
优化: 按键触发加载
第二种优化方式主要用我头几天写的 lazy-load 技术来做。
把 90% 的插件放到运行时第一次按键时再加载,而不是启动的时候就加载好。
因为lazy-load那篇文章已经详细说明了用法,这里就不再复述。
最后
用我上面的三个优化步骤,可以把Emacs启动时间减少到 1/10.
Enjoy!
14 个赞
走个题,如果用use-package
,把非必要packages(对于我来说就是除了counsel和org的其他)全部加上:defer 3
, :defer 5
就可以了,100+以上packages启动耗时5秒
直接上图,258 package 1.6s。
用use-package
,加上一些其他优化技巧,2s左右很正常。命令行下0.8s左右。
1 个赞
我的配置有184 (length load-path) 个package, 优化后启动只需要 0.6s
如何优化:
- 参考 doom-emacs 作者写的 how-is-dooms-startup-so-fast
- 除上面说的benchmark-init外,还有一个esup可供测试
- 使用use-package以autoload所有插件
- 启动时不要直接打开相应的mode, 可以使用after-init-hook, emacs-startup-hook,或者 window-setup-hook,比如可以用
(use-package yasnippet
:hook (after-init . yas-global-mode))
- 除了after-init-hook外,还可以自定义启动hook并且延时运行,这样可以减少很多启动时间
(defvar maple-init-hook nil
"Custom init hook.")
(maple/add-hook 'emacs-startup-hook
(run-with-idle-timer 0.1 nil (lambda() (run-hooks 'maple-init-hook))))
- 最后你会发现大量的启动时间都消耗在
(package-initialize)
(我还在使用26的版本,27貌似不需要这行),所以之前我参考doom-emacs写了一个maple-package来加快emacs的启动,使用之后可以提升0.3s的启动时间
当然,这里的启动是指打开一个空的buffer,如果打开一个python文件,就会花费更多时间,更好的方式是使用emacs --daemon
, 然后用emacsclient
4 个赞
我300个包,800ms,还包括启动两个sever服务
windows下也能用吗?我windows下的启动时间2分钟,痛苦的很
我用spacemacs
,400个包,启动时间8点几秒。。。
lkpjj
9
300多package 1.6s,有一大半在package-initialize了
emacs版本?使用过类似use-package的延迟加载没?需要经常启动emacs吗?
emacs 26,同样的配置,ubuntu底下就快的很,
windows底下干掉了一大堆包还是慢,6秒左右
╼►[benchmark-init/root nil 6567ms]
├─[etags require 196ms]
│ ╰─[xref require 204ms]
│ ╰─[project require 218ms]
├─[company-dabbrev require 31ms]
├─[company-capf require 31ms]
├─[company-cmake require 78ms]
├─[company-clang require 78ms]
├─[company-eclim require 78ms]
│ ╰─[company-template require 47ms]
├─[cl require 215ms]
├─[rx require 218ms]
├─[~/.emacs.d/company-statistics-cache.el load 0ms]
├─[company-statistics require 31ms]
├─[~\.emacs.d\abbrev_defs load 16ms]
├─[default load 281ms]
├─[paren load 250ms]
├─[cus-start require 204ms]
├─[cus-load require 218ms]
├─[init-better-defaults require 764ms]
│ ├─[grep require 187ms]
│ ├─[compile require 218ms]
│ │ ╰─[comint require 203ms]
│ │ ├─[ansi-color require 189ms]
│ │ ╰─[ring require 203ms]
│ ├─[ibuffer require 207ms]
│ │ ╰─[ibuffer-vc require 78ms]
│ │ ╰─[ibuf-ext require 200ms]
│ ├─[thingatpt require 187ms]
│ ├─[popwin require 141ms]
│ ╰─[filenotify require 188ms]
├─[init-keybindings require 203ms]
├─[init-company require 0ms]
├─[init-cc-mode require 16ms]
├─[init-yasnippet require 422ms]
│ ╰─[yasnippet require 219ms]
├─[init-elisp require 0ms]
├─[init-lisp require 78ms]
├─[init-hippie-expand require 0ms]
├─[init-ibuffer require 218ms]
╰─[init-elpa require 250ms]
Windows 下主要是读取文件慢,是通过msys编译的,不是原生API调用天生就慢。去掉一些比较大的包会有好转。还有一个办法就是在WSL下用。不过,还是会慢不少。