Electron Apps Causing System-Wide Lag on Tahoe
ToxicLand (via Hacker News):
Using an M1 Max MacBook Pro, having Electron-based apps open / not minimized causes a huge lag.
CPU and GPU usage remains low, but if I have Discord and VS Code open, moving windows, scrolling is stuttery. It happens even when only Discord is open but it gets worse if I open a second Electron app.
This is kind of weird because while having Discord open and I’m in Chrome, the lag still occurs, but it’s fixed if I minimize.
After a lot of digging, I believe I’ve found the root cause of the WindowServer GPU spike on macOS 26 when shadows are enabled.
It turns out Electron was overriding a private AppKit API (
_cornerMask
) to apply custom corner masks to vibrant views.This method is called by WindowServer to calculate the shadow of the window. I’m speculating that Apple uses some sort of memoization by reference, and this method breaks the memoization and forces WindowServer to repeatedly recalculate and repaint the shadow.
🤔 What’s particularly funny is that even a simple override that does nothing but call
super
still presents the issue.
Previously:
- macOS 26.0.1
- macOS Tahoe 26
- NSAutoFillRequiresTextContentTypeForOneTimeCodeOnMac
- Is Electron Really That Bad?
12 Comments RSS · Twitter · Mastodon
How do they manage to break everything with such an astounding incompetency? How was none of this nonsense (or the password auto-complete nonsense) caught in regular QA testing? It's not like one has to work hard to find an Electron app in the wild? Is there even such a thing as "regular QA testing" with this dumb company?
Also, I know, I know, "eLeCtRoN bAd, iT's BaD mAnAgEmEnT, nOt ThE eNgEnEeRiNg", but how dumb can engineering be to introduce such a behavior, with such assumptions, without even testing what happens when a developer overrides this property? AppKit has a rich history of not breaking SPI and being mindful to how private API might be used by enterprising developers. All that is gone I guess, because glass and management and "design is how it works".
It's not just Electron. I noticed laggy, stuttering scrolling in MS Edge under Tahoe. It was just fixed in the last update.
I experienced the lags early on and it was especially noticeable on my Intel Mac.
I figured out that turning off transparency pin Accessibility > Display improved things significantly.
I had not made the link with Electron apps yet, but I do indeed have at least Slack running on my Mac continuously.
@Charles I think what you experienced is another issue:
https://mjtsai.com/blog/2025/08/01/nsautofillrequirestextcontenttypeforonetimecodeonmac/
To me it feels like that’s a difference in platform backwards compatibility policy:
Microsoft: We will bend backwards to ensure that private API you abused 15 years ago stay and works the same, even writing shims to simulate old functionality for old apps if we need to change it.
Apple: Use private APIs at your peril.
I can understand both.
@Charles: Edge is an electron app as well. Right now the only fix for the apps that use old electron is to run
launchctl setenv CHROME_HEADLESS 1
on every start, which has a side effect of making electron stop drawing the window shadows (which is the culprit). When I do this, Edge loses its window or menu shadows just like any other Electron app (and yes, the system feels fast again).
@Tomas It’s not quite so black-and-white, though. Apple does in some cases do per-app compatibility modes. And in this case there are intermediate steps that could have been taken, like announcing that this private API was changing and warning developers to stay away from it. The release notes sometimes mention stuff like this. Are we to assume that nobody noticed the effects of this change, even though Electron apps are a huge portion of the platform? Putting aside public vs. private API, I would have thought that they do testing to make sure there aren’t obvious regressions with key apps.
@Michael Tsai: Thank you for correction, I didn't realize Apple does per-app compat too. And I agree it would be great if they did uncover the regression, not just because of numerous spillover effects.
For example, I reported garbled sound on macbook when memory pressure is high, but it seems to have also been caused by this - the high priority WindowManager being busy with redrawing hundreds of shadows per second meant that coreaudiod didn't get enough cycles to put out the audio in time.
I have gathered the fixed versions and asked Claude for a script to detect apps with outdated Electron:
https://gist.github.com/tkafka/e3eb63a5ec448e9be6701bfd1f1b1e58
Sadly, I don't have a single fixed app on my mac yet:
❌ OpenMTP.app: Electron 18.3.15
❌ Visual Studio Code.app: Electron 37.3.1
❌ Cursor.app: Electron 34.5.8
❌ Windsurf.app: Electron 34.4.0
❌ Slack.app: Electron 38.1.2
❌ Claude.app: Electron 36.4.0
❌ Signal.app: Electron 38.1.2
❌ Figma Beta.app: Electron 37.5.1
❌ Beeper Desktop.app: Electron 33.2.0
❌ Electron.app: Electron 36.3.2