High level overview of Electron performance tips and tricks, and a look at the new C++ architecture of Mailspring (https://getmailspring.com/) — presented Nov. 1st at the Bay Area Electron Meetup
2. Me
• Mac & iOS ➡ React & Electron
• Run a small team doing React /
mobile dev, now working on
Mailspring.
• Led the team building Nylas
Mail from 2014–2016.
3. Nylas Mail ➡ Mailspring
• May 2017: Nylas API business booming—engineers
pulled from Nylas Mail to fight growth fires!
• Sept 2017: Nylas Mail officially sunset, re-licensed
under MIT. 🎉
Mailspring: Fix longstanding issues, use Pro version
revenue to run service and pay core contributors.
4.
5. ☄
Complaints about Nylas Mail
• Long startup time
• High battery impact
• Uses too much RAM*
Electron
😡 😤🚀🔥
6. • Long startup time
• High battery impact
• Uses too much RAM*
👷(
Complaints about Nylas Mail
Electron
7. Reducing startup time
• Start loading a BrowserWindow as fast as possible
• Watch out for sync I/O in main process
• Use the ASAR format in production
• Load less JavaScript (on launch)
14. Devtron
• Easy to find heavy dependencies and see total JS
loaded.
• `request` is 910k of JS. Can you use Fetch APIs?
`bluebird` is 180k of JS. Can you use native Promise?
Nylas Mail
15. Devtron
Mailspring
• Easy to find heavy dependencies and see total JS
loaded.
• `request` is 910k of JS. Can you use Fetch APIs?
`bluebird` is 180k of JS. Can you use native Promise?
16. Devtron
• Some things you can’t avoid… but you can load
later. Who needs spellcheck in the first 500ms?
More UI Plugins SpellcheckerCore Window
Interactive in 1.0s
20. Reducing Energy Impact
• Check for animations / needless layout
• Minimize use of setTimeout, setInterval. Don’t
wake and perform work if you don’t need to.
• Attach an event listener to `blur` that toggles
a CSS class, use it to prevent animations.
23. setTimeout / setInterval
• Use smarter polling strategies:
• Change polling rate based on Electron
PowerMonitor state.
• Poll when important events occur (window
focus event) rather than all the time.
24. But… what if it’s not enough?
• Need to sync mail every few minutes,
sometimes this requires polling.
• Need to keep IDLE connections open
to mail providers.
• Need to keep streaming connection
open to Mailspring server.
👷(😭 😢
27. Enter C++
• Command line C++ processes replace the
background “work” window.
• Read actions on stdin, write JSON event
stream to stdout.
• Main window spawns these processes, binds to
their stdio streams, and re-broadcasts events.
28. C++ tradeoffs
• In JavaScript, control flow is hard.
(Promises, async/await, etc.)
• In C++, control flow is easy but memory is hard.
(Sync I/O on a few threads.)
• The SQLite bindings for C are incredibly fast.
• Shipping C++ cross-platform is hard.
29. C++ is kind of… pretty?
• The C++11 syntax is really elegant.
• Modern features like condition_variable allow
the sync engine to do almost no polling.
32. Takeaways
• Keep your dependencies light, use built-in APIs
when possible. Check require tree with Devtron!
• Use “Paint Flashing” to identify crippling CSS /
layout issues. Minimize timer use if possible.
• Combining Electron and C++ (or Haskell, or Go,
etc.) isn’t that crazy.