# Performance

> Use when an Electron app is slow or janky — slow startup/cold start, high RAM, frozen window, blocked main process or UI thread (démarrage lent, fenêtre figée, app qui rame, jank). Covers the performance checklist, lazy `require()`, profiling with `--cpu-prof`/`--heap-prof`, offloading CPU work via `utilityProcess.fork`/worker threads, `requestIdleCallback`/Web Workers, bundling, `Menu.setApplica…

- **Type:** Skill
- **Install:** `agentstack add skill-ohvignas-claude-electron-skills-performance`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [ohvignas](https://agentstack.voostack.com/s/ohvignas)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [ohvignas](https://github.com/ohvignas)
- **Source:** https://github.com/ohvignas/claude-electron-skills/tree/main/skills/performance

## Install

```sh
agentstack add skill-ohvignas-claude-electron-skills-performance
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Electron Performance

## Overview
Electron ships a full Chromium + Node.js runtime, so performance problems are almost always self-inflicted: heavy work runs on the main process (the UI thread) or at startup before the user needs it. The mental model: **measure first, defer everything you can, and never block the process that paints the window.**

## When to use
- Cold start is slow; the splash/window takes seconds to appear.
- The window freezes, beach-balls, or stops responding to clicks while a task runs.
- High memory or CPU at idle; a `require()` of one module spikes startup.
- You want to offload CPU-heavy work (parsing, crypto, image/PDF processing) off the main process.
- You're auditing bundle/`node_modules` size or considering V8 startup snapshots.

**When NOT to use:** for *rendering* jank caused by layout/paint, profile in the renderer's DevTools Performance tab first; for crashes/OOM kills see `crash-diagnostics`.

## Quick reference
| Symptom / goal | Fix |
|---|---|
| Don't know what's slow | Profile **first**: `node --cpu-prof --heap-prof -e "require('module')"`, then DevTools |
| Heavy module loaded but rarely used | Move `require()` out of top level into the function that uses it (lazy require) |
| Main process frozen | Offload CPU work to `utilityProcess.fork()`, `worker_threads`, or a `BrowserWindow` |
| Sync I/O on main | Use async (`fs.promises.readFile` not `fs.readFileSync`); avoid sync IPC & `@electron/remote` |
| Renderer jank | `requestIdleCallback()` for low-priority work; `Web Worker` for CPU loops |
| Slow polyfills | Target latest ES; drop `jQuery`/polyfills Chromium already ships |
| Network on startup | Bundle static fonts/icons/data; audit with DevTools **Network** tab |
| Many `require()` calls | Bundle with Webpack/Parcel/rollup so the cost is paid once |
| Default menu overhead | `Menu.setApplicationMenu(null)` before `app` is ready if you use a custom/frameless menu |
| Shrink startup heap | V8 startup snapshot (`v8_context_snapshot.bin` via `electron-mksnapshot`) |

## Example
Before/after: a `parse-heavy` module loaded eagerly on the main process froze the window. After, it's lazily required **inside a `utilityProcess`** so the main thread stays free.

```js
// main.js — AFTER
const { app, BrowserWindow, utilityProcess } = require('electron')
const path = require('node:path')

function createWindow () {
  const win = new BrowserWindow({ width: 900, height: 600 })
  win.loadFile('index.html')
  return win
}

app.whenReady().then(() => {
  const win = createWindow()

  // CPU-heavy parsing is forked into a Node child process backed by
  // Chromium's Services API — it runs OFF the main process, so the
  // window never freezes. modulePath is resolved relative to main.
  const child = utilityProcess.fork(path.join(__dirname, 'parser.js'))

  child.on('message', (result) => {
    // Result arrives async; UI stayed responsive the whole time.
    win.webContents.send('parsed', result)
  })
  child.postMessage({ file: '/path/to/huge.csv' })
})
```

```js
// parser.js (the utility process) — heavy require() lives HERE, not on main.
process.parentPort.on('message', (e) => {
  // Lazy require: the 100k-line dependency is only loaded when work arrives,
  // and inside the child process — never blocking app startup.
  const { parse } = require('some-heavy-parser')
  const rows = parse(require('node:fs').readFileSync(e.data.file, 'utf8'))
  process.parentPort.postMessage(rows.length)
})
```

## Common mistakes
- **Profiling by guessing.** The docs are explicit: measure before optimizing. A "fast" module can pull a 100k-line JSON on `require()`.
- **`require()` at the top of `main.js` for everything.** Top-level requires run at startup whether or not the feature is used. Defer them.
- **Doing CPU work on the main process** (or via sync IPC / `@electron/remote`). It blocks the UI thread for every window. Use `utilityProcess`/`worker_threads`.
- **Synchronous Node APIs** (`fs.readFileSync`, `child_process.execSync`) on the main process — always prefer the `fs.promises` / async variant.
- **Shipping `devDependencies` & unused `node_modules`** into the package — they bloat install size and `require()` graphs. Bundle and prune.

## Reference
Full API tables: [reference.md](reference.md)

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [ohvignas](https://github.com/ohvignas)
- **Source:** [ohvignas/claude-electron-skills](https://github.com/ohvignas/claude-electron-skills)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** yes
- **Shell / process execution:** yes
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-ohvignas-claude-electron-skills-performance
- Seller: https://agentstack.voostack.com/s/ohvignas
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
