用 Dumper 提升 Emacs 的启动速度
今天尝试了一下 emacs 的 protable dumper 功能,它把加载的 package 导出到一个外部文件中,然后启动 emacs 时直接 加载这个文件,这样比一个一个 package 的加载速度快很多。lazyload 是延迟到首次调用时才加载 package,这会导致两个问题:
- 首次调用的延迟很恼人
- 在首次进入 prog-mode 或者 org-mode 时,停顿很明显。
- 刚启动 emacs 时响应延迟
- 一些通过timer或者延迟
after-init-hook
实现的 lazyload 会导致一些包在启动 emacs 后扎堆加载。
protable dumper却可以规避这两个问题,因为在加载 dump-file 后,所有包已经准备就绪。
不过当前 protable dumper 也并不完美:
- 比正常启动 emacs 要多出一个导出 dump-file 的过程。
- 一些包导出时会出错等等。
所以,我当前的方案是把 protable dumper 作为补充方案,解决 lazyload 的上述两个问题。
1. Config
主要参考了网上的这篇文章:Painless Transition to Portable Dumper 。这篇文章写得很详尽,把配置思路和踩的一些坑都说的很清楚。下面的内容只是它的一个简述和总结。
1.1. 定制需要 dump 的包
有两类包是我需要dump的:
- 首次加载延迟很久的包
- 启动emacs马上需要用到的包
Emacs 提供了 dump-emacs-portable
函数把当前已经加载的包导出到 dump-file。为了只导出特定的包,可以单独提供一个为 dump 所需的配置文件,然后执行下面命令导出 dump-file:
emacs --batch -q -l dump.el
在 dump.el
中只加载特定的 package,然后调用 dump-emacs-portable
函数。
(require 'package) (package-initialize) (setq yx/dumped-load-path load-path yx/dumped t) (dolist (package '(elec-pair savehist winner flyspell flymake eglot use-package ;; evil evil evil-owl evil-mc evil-escape evil-surround evil-matchit evil-visualstar vimish-fold evil-vimish-fold ef-themes)) (require package)) ;; pre-load themes (load-theme 'ef-duo-light t t) ;; dump image (dump-emacs-portable (expand-file-name "emacs.pdmp" user-emacs-directory))
1.2. 加载 dump-file 启动 emacs
Emacs 提供了 --dump-file
命令行参数,用来在启动 emacs 加载制定 dump-file:
emacs --dump-file="/User/yx/.emaorg-super-agenda cs.d/emacs.pdmp"
为了不影响 emacs 的正常启动方式,即执行 emacs
命令仍按之前的方式启动,需要在 init.el
文件中添加dump-file启动的条件分支。在上面的 dump.el
中添加了 yx/dumped
变量,并且设置为 t
,这样在导出的dump-file中也会有这个变量,然后在启动过程中就能通过判断这个变量来判断启动方式。下面是 init.el
中的判断逻辑:
(if yx/dumped
(dumped-run)
(normal-run)
)
1.3. Protable-dumper的一些问题
- 一些包导出报错(global-undo-tree, org-super-agenda )
- 一些默认模式没有启动(transient-mark-mode, global-font-lock-mode)
--dump-file
后的路径名中不能使用~
scratch buffer
有点异常
这些问题在Painless Transition to Portable Dumper 都有解决。
2. 结语
由于之前的配置几乎都是懒加载的,启动速度已经在 0.7 ~ 0.8 左右了,加上 dumper 后速度稍微变慢了一点,在 0.85 左右。不过整个使用过程比以前丝滑了不少。
最后再说说自己使用中一个不好的感受吧:
每次添加 package 后都要 dump 一次,很麻烦,而且性能提升感受并不明显。 想了一些改进的办法
- 隔一段时间 dump 一次,不要每次添加软件都 dump
- 坚持只 dump 启动延时很高的 package