第一次打开org 文件特别慢

忍受了很久Windows 的Emacs 启动慢。
经过仔细测试,发现启动慢的原因主要是Org-mode 引起。
1 . Emacs -q 本体启动很快,估计在300ms. 但是打开一个空的org文件竟然感觉到有1s 多的延迟。
2. 最简化配置,只有benchmarking session 用于测量时间。本体585ms,空org需要1797ms
3. 随着增加越来越多的功能包,打开org-mode的时间会急速飙升。本体3798ms, 空org需要9762ms

不知道有人知道是什么原因引起org加载慢吗?
Emacs 28.0.50 /27.1
Windows 10 / Mac 11.1
配置:Purcell Emacs ,全部包的安装使用package.el, 没有使用lazyload。

2 个赞

用dump吧.

日常使用portable dumper - Emacs-general - Emacs China (emacs-china.org)


(require 'package)
(package-initialize)

(message "Dumping start at %s" (current-time-string))

(global-font-lock-mode) ; highlight


(load-file (concat (file-name-as-directory user-emacs-directory) "init.el"))

(dolist (package '(
					   prog-mode cc-mode cpp python sh-script js json thingatpt lisp-mode scheme elisp-mode 
					   dired proced elec-pair project xref paren midnight dash text-mode pcomplete
					   recentf saveplace woman man
					   em-script esh-cmd esh-io em-script em-xtra em-glob em-tramp em-basic eshell vc-git em-hist em-unix  em-cmpl em-ls em-term em-alias em-banner em-pred em-prompt
					   org org-table org-timer org-list org-protocol org-archive org-clock org-agenda org-attach org-capture org-compat org-faces org-feed org-goto ol-irc ob-C ob-js ob-J ob-abc ob-calc ob-clojure ob-comint ob-core ob-emacs-lisp ob-eshell ob-haskell ob-java ob-lisp ob-lua ob-makefile ob-octave ob-org ob-perl ob-python ob-ruby ob-scheme ob-shell ob-sql

					   ))
  (require package))

(defconst *dump* t
  "Using dumping now.")

;; dump image
(dump-emacs-portable "~/.emacs.d/emacs.pdmp")

试试 emacs -q 然后 M-x profiler-start 再 load 你的 ~/.emacs。

之前也考虑过dumper,但是想改配置的话,还是要重新dump,比较麻烦。如果只是日常用,启动10s 钟也是可以的,反正一天就启动一两次。 就是要改配置的时候不方便。

改配置可以在wsl或者docker里改,

而且小改(几个变量)之类的不用重新dump.

windows上load-theme很耗时间,直接在dump里加载了,启动大幅变快(window-setup-hookbefore-init-time的时间)

其他缺点就是eww和package-install的时候会闪退,

但打开之后emacs就是完全就位状态(如果你把你大部分包都dump了),不会在`(require …)的时候卡顿.

非常的爽…

1 个赞

看来是window版本emacs的硬伤,想要好的体验还是得回到Linux上来。Dump可以试试,多谢你的建议。

1 个赞

这个org文件是一个空的文件。

CPU profiler started
Loading c:/Users/Aqua/.emacs.d/custom.el (source)...done
Loading c:/Users/Aqua/.emacs.d/.session...done
Error enabling Flyspell mode:
(Searching for program No such file or directory ispell)
Restoring clock data
Loading c:/Users/Aqua/.emacs.d/org-clock-save.el (source)...done
Desktop: 8635.51ms to restore ~/Desktop/org.org
Desktop: 860.42ms to restore ~/.emacs.d/init.el
Desktop: 428.99ms to restore nil
Wrote c:/Users/Aqua/.emacs.d/.emacs.desktop.lock
Desktop: 1 frame, 3 buffers restored.
Desktop restored in 9959.84ms
Loading c:/Users/Aqua/.emacs.d/recentf...done
Cleaning up the recentf list...done (0 removed)
Saving file c:/Users/Aqua/.emacs.d/custom.el...
Wrote c:/Users/Aqua/.emacs.d/custom.el
init completed in 3898.28ms

profiler-report 的结果如下:

             304  62% - normal-top-level
         304  62%  - command-line
         216  44%   - startup--load-user-init-file
         212  43%    - load
         212  43%     - load-with-code-conversion
         212  43%      - eval-buffer
         212  43%       - require
         211  43%        - apply
         211  43%         - sanityinc/require-times-wrapper
         211  43%          - let*
         211  43%           - prog1
         211  43%            - apply
          74  15%             - #<subr require>
          74  15%              - load-with-code-conversion
          74  15%               - eval-buffer
          34   6%                + package-initialize
          21   4%                + require
           9   1%                + internal-macroexpand-for-load
           4   0%                + if
           2   0%                + let
           2   0%                + desktop-save-mode
           1   0%        + load-with-code-conversion
          88  18%   - run-hooks
          22   4%    + global-diff-hl-mode
          21   4%    - projectile-mode
          20   4%     + byte-code
           7   1%    + session-initialize
           4   0%    + #<lambda -0xcffffff3065e2fd>
           3   0%    + #<lambda 0x3000143d8b4f713>
           3   0%    + ipretty-mode
           3   0%    + global-auto-revert-mode
           1   0%    + which-key-mode
           1   0%    + hes-mode
         183  37% - ...
         179  36%  - sanityinc/desktop-time-restore
         179  36%   - let
         179  36%    - prog1
         179  36%     - apply
         179  36%      - #<compiled 0x10e3a2e875bd5013>
         179  36%       - load
         179  36%        - load-with-code-conversion
         179  36%         - eval-buffer
         179  36%          - desktop-create-buffer
         179  36%           - apply
         179  36%            - sanityinc/desktop-time-buffer-create
         179  36%             - let
         179  36%              - prog1
         179  36%               - apply
         179  36%                - #<compiled -0x15031bfba9e119>
         179  36%                 - desktop-load-file
         176  36%                  - autoload-do-load
         134  27%                   + byte-code
          31   6%                   - do-after-load-evaluation
          31   6%                    - run-hook-with-args
          28   5%                     + eval-after-load-helper
           3   0%                     + eval-after-load-helper
          10   2%                   - defconst
          10   2%                    - org-version
           7   1%                     + locate-library
           3   0%  + cons
           1   0%    Automatic GC
  

我尝试过(use-package org :demand)让emacs启动的时候就加载org,甚至(setq use-package-always-demand t),但是打开第一个org-mode的buffer的时候还是会卡一下。。。

1 个赞

(setq org-modules-loaded t)

4 个赞

一秒左右加载完一个模块是可以理解的,但是要加载10s ,肯定是有问题的。我估计是package.el 的autoload 对org-mode产生了影响,使得它想要加载所有的包,而其他major-mode 只是加载跟自己相关的包。因为我之前用Lazyload 的时候是没这个问题。

谢谢,现在是秒开了~~

我用这个选项的话,org-mode 的加载时间减少一半。 :+1:

我用(setq use-package-always-demand t),启动emacs要十几秒 :joy:。刚刚用esup看了下根org-mode相关的包需要4,5秒钟左右,可能是因为lazy-load才卡吧。。

我是mac下,第一次打開6MB的org文件特別慢,需要20秒。

但是打開小org文件很快,一兩秒。

但是的但是,如果先打開小org,然后再打開6mb的也只要一兩秒了。莫名其妙不。

我估计是package.el 生成的autoload 和.elc 文件造成的问题。我现在使用git-submodule 进行包管理,同样配置,并不会影响org-mode,org-mode在windows上的时间保持在1s左右(Emacs -Q也是这个时间)。
使用package.el 时,如果出现问题,很难定位问题,浪费我很多时间去找问题。

还有一个好处是,恢复session 的时间大幅度提升了,恢复buffer的时间基本是10ms 以内,真爽。
29个buffer 恢复,才3s不到,如果在Mac,估计更快。

1 个赞

我设置了这个选项,第一次打开org文件还是很慢啊

我现在的解决方案:在 init 文件的最后,用 find-file 打开一个指定的 org文件,然后使用 kill-buffer 关掉。

这实际没有解决第一次打开 org 文件慢的问题,但是把首次打开加载时间转移到 emacs 初始化时间里了。对于我这种对 emacs 初始化时间不在乎的人没啥影响,后续再打开 org 文件非常顺滑

你这个也是一个很好的思路呢。 :grinning:

我也是在配置文件的最后, find-file了一个org文件, 不过开始时不是为了后续打开org文件更顺滑, 而只是因为这个文件比较常用就写进去了

这个配置效果不错,我是这样用的。
(use-package org :defer 0.1
  :init
  ;; disable org-modules
  (setq org-modules-loaded t))

启动0.1秒后,加载org。并且禁用org-modules。

这样不会在启动时卡Emacs,第一次打开org文件也很快。