Skip to main content
Back to Blog

Improving the Performance of Electron Apps

Leading the development of electron-react-boilerplate for over 5 years has taught me quite a bit about performance challenges with electron and optimizing electron apps. Contrary to popular belief, I believe electron apps can perform as well as native desktop apps.

Before reading this, it's important to recognize that applications will certainly benefit a lot more from fundamental architectural improvements as opposed to the optimizations discussed here. If you'd like to read more about architectural improvements, read the slack posts in the "Classic Electron and JS Perf Readings" section below.

Strategies for Performance Improvement

Over the course of maintaining electron-react-boilerplate, I've noted the following strategies as the most impactful improvements to be made to electron apps.

1. Always use a bundler

require() calls often bottleneck the initialization time of your app. The require algorithm is recursive and synchronous (so it blocks the main thread).

Sam Saccone, a performance engineer at Google, debugged Atom's startup performance:

Most of the startup time is spent requiring modules and deadlocked in node.js execution before the initial paint in the browser is ever fired, resulting in slow feeling startup experience for end users, by potentially bundling all of the dependencies into one file there could be a sizeable perf savings.

https://github.com/atom/atom/issues/9720#issue-118095913

Flamegraph based on Atom's startup performance

Don't go down this path. Use a bundler!

2. Defer non critical imports

This can be done in a number of ways. One way of reducing the up front cost of loading your application is to use route-based code splitting and an app shell architecture. While working as a consultant for companies that use electron-react-boilerplate, I've used route-based code splitting optimizations to bring down startup time from ~10sec to ~3sec.

3. Debug Devtools and Content Tracing

Applying traditional browser performance debugging techniques to Electron apps is a good starting point. https://www.electronjs.org/docs/latest/api/content-tracing

4. Fallback to WebAssembly or native node modules

If your app often performs computationally expensive tasks, its likely a good move to run those tasks in WebAssembly. WASM serves as a shortcut to the JavaScript engine's optimizer. Rather than the JavaScript engine having to execute and optimize code at runtime, WASM executables are optimized ahead of time and therefore provide much more deterministic performance characteristics.

5. V8 Snapshots

Snpashots are a feature of V8, Chrome's JS engine, which allows snapshotting an initialized heap and reusing it. This avoids reinitializing objects on the heap every time your app starts up. The V8 team wrote a great article on V8 Snapshots, which I highly recommend reading. I'd also recommend checking out electron-link, a tool that allows leveraging V8 Snapshots to improve electron's startup performance.

6. Monitor Performance in Production

You can't optimize what you don't measure. Measuring what's slow for your users helps you prioritize optimizing the right things.

As an example, the VSCode team measures the input latency to identify regressions between releases.

At Palette, we're building performance monitoring for Electron apps. We monitor the performance of user interactions like scroll, keypress, and click events.

Here's what the Palette dashboard looks like:

You can sign up today by joining our waitlist, which has companies like Notion, Wayfair, Dropbox, and more!

📚 More Readings

For those who want to read more in-depth articles on optimizing the performance of Electron and browser apps, I recommend checking out the case studies and perf readings below.

🙇‍♀️ Case Studies

  1. Samcone Debugging Atom Perf
  2. Atom Team Debugs Atom Performance

📖 Electron and JS Perf Readings

  • VSCode's Text Buffer Reimplementation
  • Seena Burns: Debugging Electron Memory Usage
  • Seena Burns: Thumbnailing is Isolate: Background Workers in Electron
  • Maybe you don't need Rust and WASM to speed up your JS
  • Oxidizing Source Maps with Rust and WebAssembly
  • Slack: Chrome Tracing for Fun and Profit
  • Performance Calendar: A collection of front end performance posts
  • How we parallelized our node service by 30x
  • 600k concurrent websocket connections on AWS using Node.js
  • I have been underestimating JS Performance

Stop guessing why your frontend is slow

Palette’s production JavaScript profiler and interaction performance metrics tell you why.

Palette is the most helpful tool we have for identifying the root cause of performance issues.

John Ryan
John RyanEngineering Manager at Notion
Book a Demo