emacs-exwm / exwm

Emacs X Window Manager
https://elpa.gnu.org/packages/exwm.html
GNU General Public License v3.0
236 stars 10 forks source link

Opening large (>1MB) images and PDFs makes EXWM/Emacs slow #24

Closed moritzschaefer closed 6 months ago

moritzschaefer commented 7 months ago

When opening large PDFs and images, switch to and back from the image-containing workspace is horribly slow (every keystroke takes seconds, including opening of which-key). This seems to be cause by the image being visible as everything runs smooth, when the image/PDF is invisible. Furthermore, the slowdown seems to be proportional to the file size.

htop shows 100% CPU usage by emacs, which seems to be attributable to a high number of redisplay_internal calls. Can I somehow find out what exactly triggers the excessive number of redisplay calls?

The slow-down also leads to thes warning: ⛔ Warning (emacs): [XELB] Retrieve reply timeout, which is why I suspect it has to do with EXWM itself?

Profile

I profiled while switching back and forth between workspaces (one of them containing a large image or PDF)

CPU

       45439  59% - redisplay_internal (C function)
       45287  59%  + page-break-lines--update-display-tables
         140   0%  + eval
           6   0%  + exwm-layout--refresh
           2   0%  + window--adjust-process-windows
           2   0%  + mode-line-default-help-echo
           1   0%  + redisplay--pre-redisplay-functions
       17868  23% - command-execute
       17868  23%  - funcall-interactively
       17779  23%   - #<lambda 0x10a2e7b5>
       17779  23%    - exwm-workspace-switch
       17779  23%     - apply
       17779  23%      + ad-Advice-exwm-workspace-switch
          86   0%   + #<lambda 0x10a2e7b6>
           1   0%   + profiler-start
           1   0%   + file-notify-handle-event

Notably: page-break-lines-mode is inactive in the image/PDF. I suspect it gets called in a non-PDF buffer

Mem:

    419,499,943  92% - timer-event-handler
    419,323,335  92%  - apply
    310,811,551  68%   + which-key--update
    102,210,631  22%   + savehist-autosave
      5,063,016   1%   + auto-revert-buffers
        633,480   0%     posframe-hidehandler-daemon-function
        136,722   0%   + save-some-buffers
        135,168   0%   + #<subr F616e6f6e796d6f75732d6c616d626461_anonymous_lambda_9>
        130,280   0%   + exwm-input--update-focus-commit
         84,343   0%   + fancy-battery-update
         19,008   0%     exwm-layout--on-echo-area-change
         17,650   0%   + gac--after-save
          9,517   0%   + display-time-event-handler
          1,433   0%   + org-clock-update-mode-line
          1,056   0%   + show-paren-function
        147,840   0%  + timer-activate-when-idle
         18,352   0%  + timer-activate
          7,744   0%    timer-inc-time
     22,605,746   5% + redisplay_internal (C function)
      8,561,381   1% + command-execute
        694,114   0% + xcb:-connection-filter
         36,944   0%   exwm-layout--on-echo-area-change
         30,610   0% + ...

Any support would be highly appreciated (this is bugging me for years really). If this is likely not to be EXWM-related, I'll move on to spacemacs support.

minad commented 6 months ago

@moritzschaefer It seems something problematic is going on with page-break-lines--update-display-tables, since it appears so prominently in the profile above. I suggest you disable page-break-lines-mode to see if the problem goes away.


I use the following small mode to achieve a similar effect as page-break-lines-mode. You could give that a try.

(defun formfeed--fontify (beg end &optional unfontify)
  (goto-char beg)
  (while-let ((pos (search-forward "\f" end t)))
    (funcall
     (if (and (not unfontify) (eq pos (1+ (pos-bol))) (eq pos (pos-eol)))
         #'add-text-properties #'remove-text-properties)
     (1- pos) pos '(face (:strike-through t :inherit shadow)
                    display (space :width text)
                    rear-nonsticky t))))

;;;###autoload
(define-minor-mode formfeed-mode
  "Prettify ^L form feeds."
  :global nil
  (cond
   (formfeed-mode
    (jit-lock-register #'formfeed--fontify))
   (t
    (jit-lock-unregister #'formfeed--fontify)
    (formfeed--fontify (point-min) (point-max) t)))
  (jit-lock-refontify))
walseb commented 6 months ago

Also, in case that doesn't help, you could try using PDF-tools if you aren't already. I believe it uses a faster display engine than the built-in PDF viewer. It might not show up in the profiler. As for the images, I'm getting massive slowdown with large images also, but I think this is due to Emacs, not EXWM.

moritzschaefer commented 6 months ago

Thank you for your comments!

The problem comes and goes (e.g. when I close the PDF and open it again, the issue goes away for some time).

I also once deactivated each of the minor modes sequentially (including page-break-lines-mode), but the problem persisted. I do use pdf-tools already, so nothing to gain hear I am afraid.

I'll try your script @minad, thanks!