So you just made a nice & shiny new app with Electron. It works as expected, has a beautiful UI,
eats a lot of RAMandis slow, right?
Introduction
If you don't know that already, Electron is an open-source framework for building cross-platform desktop applications using HTML, CSS & (duh) JavaScript. It was initially called Atom Shell and was developed by Github to power their text editor - Atom.
Everything sound great, right? You don't need to learn another language to create cross-platform apps and instead utilize your existing knowledge.
Unfortunately, Electron has some downsides. To render your application UI, it uses Chromium, which is always bundled in your final application. Because of that:
- Size of application built with Electron is typically around ~120 MB.
- Electron apps usually use a lot of RAM.
- UI might feel a bit slow, especially on the older computers.
Now, even though we can't just delete the whole Chromium from our app and reduce it's size, we can still do something about the RAM usage & speed.
That's why I would like to show you 4 tips on how to make your Electron app faster!
1. Use V8 Engine code cache
Chrome V8 is basically a JavaScript engine, that powers both Node.js & Chromium browser. One of it's feature is the code caching, which can speed up instantiation time of you app.
To make sure this feature is enabled, we will use a package called v8-compile-cache
, created by Andres Suarez:
# Install the package
$ npm install v8-compile-cache
and then, in your entry module add the following code:
require('v8-compile-cache');
// or, using ES6 `import`:
// import 'v8-compile-cache';
Note: Take a look at the benchmarks to see how
v8-compile-cache
speeds up popular modules 😄
2. Use a module bundler
This suggestion is especially useful in larger projects, that use a good amount of packages. Using a module bundler, like Webpack will enable features like tree shaking and code splitting, which will make your code smaller & faster.
You will also be able to use some of the community-made plugins & loaders.
3. Use faster JavaScript methods, especially when working with DOM
Look at the following 2 lines of code:
const elementOne = document.getElementById('one');
const elementTwo = document.querySelector('#one');
They both do the same thing - find the DOM element. But take a look at the performance benchmark:
As you can see, the first method is more than 2 times faster, than the second one. And yes - that does not mean, that the second method is slow - both are really fast in practical use cases, but when we use a lot of slower methods in our application, replacing them with faster alternatives can really make a difference!
4. Use WebAssembly (or native addons)
This change can really speed up you application, but it also requires the most amount of work.
If your application has to, for example, calculate on a very big numbers really fast or inspect large amounts of data, JavaScript might be too slow 😢
That's exactly when WebAssembly and native addons comes in handy!
Take a look at my Electron application - elcalc, a calculator. To do more advanced math, I used a really nice library called math.js. Unfortunately, when I was testing advanced & complex calculations, there was a noticeable timeout between clicking the evaluate button and the result showing up. Not good...
I decided to write a simple Rust code, that will handle the math & convert it to WASM (shorthand for WebAssembly). I used a crate (something like npm package, but for Rust) called meval
, that parses math expressions and evaluated them.
To actually generate the WASM, I used wasm-pack and it's rust-webpack-template.
I also used a Webpack plugin, called optimize-wasm-webpack-plugin
, that (as it's name says) optimized WebAssembly files using binaryen.
And to lazy-load the WASM function in my JavaScript code, I used the dynamic import proposal:
import('../crate/pkg').then(async module => {
// do something
});
Now my calculator evaluates math expressions much faster 🚀
BONUS: 5. If you care about app size, use something else
If you care much about your app size, there is an alternative to Electron, called Carlo. Instead of including Chromium in your app bundle, it uses the locally installed Google Chrome browser on user's computer.
Unfortunately this means that when user does not have Google Chrome installed, your app won't launch and it will display an error.
Credits
Some suggestions listed in this post were taken from
Felix Rieseberg's Medium article, called "JavaScript on the Desktop, Fast and Slow". I highly recommend checking it out!
Thank you for reading my post! I hope you will find it useful ;)
Top comments (10)
Now the question is how we make our Electron apps smaller 😂
I think you cannot make Electron apps smaller unless you're not using Electron anymore. I am thinking there should be a possibility on creating an installable PWA that only needs internet connection in order to install and that's it. Just a thought. Haven't done it, but I think it's possible [with some workarounds].
use Tauri
tauri.studio
Since, it bundles Chromium and V8 engine with your app, you cannot reduce its size.
Carlo felt like a much better approach but I find the same problems with it.
I guess we're just simply stuck. I was thinking about creating a screenshot application but a 120 MBs screenshot app with Electron doesn't looks like it is worth it. I did use an Electron based screen recorder and it is pretty famous. It was way too slow and I had to remove it.
Carlo is no longer maintained
Instead of Carlo, I highly recommend Neutralino. It lacks some of Electron's features, but instead of bundling Chromium or looking for Chrome it uses the OS' built-in browser (for example, in Windows, edge, or Safari in Mac)
Thanks for sharing Antoni. I hadn't heard about Carlo yet, will be investigating it. ðŸ¤
I think the most promising alternative for Electron right now is Tauri.
Excellent post.