Skip to content

monkeynut.org

Smooth scrolling on Emacs on macOS

I run Doom Emacs with ultra-scroll to allow me to smoothly scroll using my trackpad. There's just one problem: occasionally the entire display will freeze for a fraction of a second while I'm scrolling, rather breaking the spell of having a responsive system.

After working through most of the suggestions on the Why is Emacs/Doom slow? to no avail, I took a stab in the dark and enabled garbage collection messages:

(setq garbage-collection-messages t)

And, surprise surprise, all of the freezes coincided with garbage collections.

Fortunately, we can solve this issue using the Garbage Collection Magic Hack (GCMH). Essentially, we run with an increased GC threshold, but then use an idle timer to (i) temporarily lower the GC threshold, and (ii) force a garbage collection. Because it's running from an idle timer, it never occurs during a user interaction (that said, it could occur just before an interaction, although in practice this hasn't been an issue for me).

It turns out the GCMH was already enable for me, but it was using a gcmh-high-cons-threshold value of 64MiB. This meant the garbage collection was activating during a typical scroll. Bumping this value to 1GiB allows scrolls to complete with incurring any garbage collection.

Here's how I set this value in my init.el:

(use-package! gcmh
  :config
  (setq
   ;; 1GiB
   gcmh-high-cons-threshold #x40000000
   ;; gcmh-verbose t
   ))

Uncomment the gcmh-verbose line if you want to verify that it's working.