2020-04-15-emacs-bankruptcy-is-fun.org (4864B)
1 #+title: Emacs bankruptcy is fun 2 #+date: <2020-04-15 Wed> 3 #+filetags: emacs configuration optimization 4 #+setupfile: ../templates/post.org 5 6 * Introduction 7 8 Since go 1.14 go released, I've had a broken =go-mode= setup on my Emacs. I was using 9 =lsp-mode= and =gopls= and well, the update broke everything. I initally try to fix it but 10 I made it worse. At the same time, I started to get fed up with some performance issue of 11 my configuration and how slow my Emacs starts, about 6s. 12 13 I, thus, declared my third Emacs bankruptcy, =:disabled= everything and slowly started 14 from scratch, with the following goal: 15 16 - Have it start quick, as less than a second, not too much more than =emacs -Q= would 17 - Disable anything that I don't use often initially 18 - Try to use as much built-in as possible (example: using =icomplete= instead of 19 =ivy=/=counsel=) 20 21 * Do I really need this feature 22 23 Following [[https://protesilaos.com/][Protesilaos Stavrou]]'s emacs videos (and [[https://protesilaos.com/dotemacs/][=dotemacs=]]) for a while now, I have a 24 tendency to try to use built-in feature as much as possible. The most obvious example is 25 using =icomplete= instead of =ivy=/=counsel=. 26 27 When I started my /bankruptcy/, I disabled every single customization I had, either using 28 =:disabled= when using =use-package= *or* the =(when nil)= /hack/. I then started Emacs 29 and acted on what was missing : 30 31 1. Do I really miss it ? An example would be, at least initially, the completion in a =go= 32 file. I do miss it, but I miss it *way less* than having Emacs lagging because of 33 =lsp-mode= and showing me wrong completion. 34 2. Is there a built-in option to what I previously used ? Here, the =icomplete= example 35 fits well, or =isearch= instead of =swiper=. 36 3. Do I need it at startup or /on-demand/ ? 37 38 * Looking into what takes time 39 40 In "Advanced Techniques for Reducing Emacs Startup Time"[fn:1], I discovered the [[https://github.com/jschaf/esup][=esup=]] 41 emacs library. In a gist, this is a profiler for Emacs. It starts a new Emacs instance and 42 look at the loading time. 43 44 #+CAPTION: esup "result" view 45 [[../images/2020-04-15-16-12-54.png]] 46 47 Then, you can do a simple loop: 48 49 - Run =esup= 50 - Look at the top result 51 - Fix it (lazy load, removing the feature, …) 52 - Re-iterate 53 54 * Loading on-demand 55 56 Once you have the setup to know what takes time and what not, it's time to look into how 57 to load the most thing on demand. 58 59 For this, [[https://github.com/jwiegley/use-package][=use-package=]] is amazing, it tremendously help autoloading modules on-demand. If 60 you are not using =use-package=, usually you are using =require=, which loads the 61 underlying source file (all of it). 62 63 With =use-package=, there is multiple ways to load on demand: 64 65 - =:commands= to add callable that will trigger loading the package 66 - =:bind=, =:bind*=, =:bind-keymap= and =:bind-keymap*= to bind key sequences to the 67 global keymap or a specific keymap. 68 - =:mode= and =:interpreter= establish a deferred binding with the =auto-mode-alist= and 69 =interpreter-mode-alist=. 70 - =:hook= allows adding functions onto the package hook 71 - =:defer= is the most generic one, all the previous keyword imply =:defer=. You can 72 specify a number of second of idle to load the package. 73 74 #+BEGIN_aside 75 In a gist for =org-babel=, use =use-package ob-python= and never call =org-babel-do-languages=. 76 #+END_aside 77 Once this is done, you are left with edge cases, like =org-babel-do-languages=. Those are 78 to be handle case by case. The good thing about those cases is that you'll learn what 79 those function do and this will give you an even better understanding of what is 80 happening. 81 82 Doing this exercise also forces you to make you see if you really use that feature or 83 not. I ended up removing entire feature from my configuration because they were taking 84 quite some time to load, and was used almost never. Instead I am forcing myself to learn 85 more what I can do with the built-in features first. 86 87 * Conclusion 88 89 All in all, this /bankruptcy/ was the most fun I had to do. I consider myself still in the 90 process but the base is there. 91 92 1. I learned a lot ! 93 2. My Emacs starts in 0.6s against previously in 5s — =emacs -q= starts in about 0.3s so 94 there is still a little bit of room for improvement. 95 3. I discovered / re-discovered a lot of built-in feature 96 4. I started documenting my configuration, see [[../configurations/emacs.org][here]]. 97 98 🎉 99 100 :update: 101 Well, I've look into the /portable dump/ feature of Emacs, thanks to [[https://archive.casouri.cat/note/2020/painless-transition-to-portable-dumper/index.html][Painless Transition 102 to Portable Dumper]]. And I am now down to =0.091s= for the startup. There is a few gotchas 103 with /portable dump/, I'll try to write about it later. 104 :end: 105 106 * Footnotes 107 108 [fn:1]: [[https://blog.d46.us/advanced-emacs-startup/][Advanced Techniques for Reducing Emacs Startup Time]]