Skip to content

Commit 3154fe2

Browse files
Add comprehensive performance diagnostics for macOS slowness debugging
- Add [PERF] logging to track app startup time and key events - Add [IPC] logging to track when renderer sends messages to main - Add performance tracking for IPC handlers (first call vs subsequent) - Enable production logging with --enable-logging flag - Track timing for: startup, window creation, ready-to-show, IPC handlers - Add script to easily view performance logs This will help identify: - Where the 1-3 second delay occurs - If it's in IPC communication, event handling, or renderer process - Why first clicks are slower than subsequent clicks - Exact timing of each operation
1 parent 158e7eb commit 3154fe2

File tree

3 files changed

+93
-5
lines changed

3 files changed

+93
-5
lines changed

electron-app/main.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,17 @@ import {
2525
const __filename = fileURLToPath(import.meta.url);
2626
const __dirname = dirname(__filename);
2727

28+
// PERFORMANCE LOGGING: Track startup time
29+
const startupTime = Date.now();
30+
console.log('[PERF] App startup began');
31+
2832
init({
2933
dsn: 'https://6974b46329f24dc1b9fca4507c65e942@o361681.ingest.us.sentry.io/3956140',
3034
release: `v${pkg.version}`,
3135
});
3236

37+
console.log(`[PERF] Sentry initialized: +${Date.now() - startupTime}ms`);
38+
3339
const store = new Store({
3440
defaults: {
3541
firstRunV1: true,
@@ -76,7 +82,7 @@ const mb = menubar({
7682
width: 362,
7783
webPreferences: {
7884
contextIsolation: true,
79-
devTools: isDev,
85+
devTools: true,
8086
preload: join(__dirname, 'preload.js'),
8187
nodeIntegration: false,
8288
},
@@ -96,6 +102,13 @@ mb.app.commandLine.appendSwitch(
96102
);
97103
mb.app.commandLine.appendSwitch('ignore-certificate-errors', 'true');
98104

105+
// PERFORMANCE DIAGNOSTICS: Enable detailed logging in production
106+
if (!isDev) {
107+
mb.app.commandLine.appendSwitch('enable-logging');
108+
mb.app.commandLine.appendSwitch('v', '1');
109+
console.log('[PERF] Production logging enabled');
110+
}
111+
99112
let sharedPaletteLink: string | undefined;
100113

101114
async function openSharedPalette() {
@@ -165,6 +178,8 @@ mb.app.on('window-all-closed', () => {
165178
});
166179

167180
mb.on('after-create-window', () => {
181+
console.log(`[PERF] Window created: +${Date.now() - startupTime}ms`);
182+
168183
// Load the Ember application using our custom protocol/scheme
169184
handleFileUrls(emberAppDir);
170185

@@ -176,7 +191,9 @@ mb.on('after-create-window', () => {
176191
});
177192

178193
mb.window?.once('ready-to-show', function () {
194+
console.log(`[PERF] Window ready-to-show: +${Date.now() - startupTime}ms`);
179195
setTimeout(() => {
196+
console.log(`[PERF] Showing window: +${Date.now() - startupTime}ms`);
180197
void mb.showWindow();
181198
}, 750);
182199
});
@@ -214,6 +231,8 @@ mb.on('after-create-window', () => {
214231
});
215232

216233
mb.on('ready', () => {
234+
console.log(`[PERF] Menubar ready: +${Date.now() - startupTime}ms`);
235+
217236
ipcMain.on('enableDisableAutoStart', (event, openAtLogin) => {
218237
// Only allow auto-start in production
219238
if (!isDev) {

electron-app/src/ipc-events.ts

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,45 @@ import { type Menubar } from 'menubar';
88
import { launchPicker } from './color-picker';
99
import { restartDialog } from './dialogs';
1010

11+
// PERFORMANCE LOGGING: Track first call vs subsequent calls
12+
const perfTracking = new Map<
13+
string,
14+
{ count: number; firstTime?: number; totalTime: number }
15+
>();
16+
17+
function trackPerf(eventName: string, fn: () => void | Promise<void>) {
18+
const start = Date.now();
19+
const stats = perfTracking.get(eventName) || { count: 0, totalTime: 0 };
20+
21+
const result = fn();
22+
23+
const duration = Date.now() - start;
24+
stats.count++;
25+
stats.totalTime += duration;
26+
27+
if (stats.count === 1) {
28+
stats.firstTime = duration;
29+
console.log(`[PERF] ${eventName} FIRST CALL: ${duration}ms`);
30+
} else {
31+
const avgOther =
32+
(stats.totalTime - (stats.firstTime || 0)) / (stats.count - 1);
33+
console.log(
34+
`[PERF] ${eventName} call #${stats.count}: ${duration}ms (first: ${stats.firstTime}ms, avg others: ${avgOther.toFixed(1)}ms)`
35+
);
36+
}
37+
38+
perfTracking.set(eventName, stats);
39+
return result;
40+
}
41+
1142
function setupEventHandlers(
1243
mb: Menubar,
1344
store: Store<{ firstRunV1: boolean; showDockIcon: boolean }>
1445
) {
46+
// Log all IPC messages for debugging
1547
ipcMain.on('copyColorToClipboard', (_channel, color: string) => {
16-
clipboard.writeText(color);
48+
console.log('[IPC] Received: copyColorToClipboard');
49+
trackPerf('copyColorToClipboard', () => clipboard.writeText(color));
1750
});
1851

1952
ipcMain.on('exitApp', () => mb.app.quit());
@@ -63,15 +96,32 @@ function setupEventHandlers(
6396
});
6497

6598
ipcMain.on('launchContrastBgPicker', () => {
66-
void launchPicker(mb, 'contrastBg');
99+
console.log('[IPC] Received: launchContrastBgPicker');
100+
void trackPerf('launchContrastBgPicker', () =>
101+
launchPicker(mb, 'contrastBg')
102+
);
103+
});
104+
105+
ipcMain.on('launchContrastFgPicker', () => {
106+
console.log('[IPC] Received: launchContrastFgPicker');
107+
void trackPerf('launchContrastFgPicker', () =>
108+
launchPicker(mb, 'contrastFg')
109+
);
110+
});
111+
112+
ipcMain.on('launchPicker', () => {
113+
console.log('[IPC] Received: launchPicker');
114+
void trackPerf('launchPicker', () => launchPicker(mb));
67115
});
68116

69117
ipcMain.on('launchContrastFgPicker', () => {
70-
void launchPicker(mb, 'contrastFg');
118+
void trackPerf('launchContrastFgPicker', () =>
119+
launchPicker(mb, 'contrastFg')
120+
);
71121
});
72122

73123
ipcMain.on('launchPicker', () => {
74-
void launchPicker(mb);
124+
void trackPerf('launchPicker', () => launchPicker(mb));
75125
});
76126

77127
ipcMain.handle('open-external', async (_event, url: string) => {

scripts/view-perf-logs.sh

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#!/bin/bash
2+
3+
# Script to view performance logs from Swach
4+
# Run this after launching and testing the production app
5+
6+
echo "=== Swach Performance Logs ==="
7+
echo ""
8+
echo "Recent logs (last 5 minutes):"
9+
echo "=============================="
10+
11+
/usr/bin/log show --last 5m --predicate 'process == "Swach"' --style compact | grep -E "\[PERF\]|\[IPC\]" | tail -100
12+
13+
echo ""
14+
echo "=============================="
15+
echo "To see all logs, run:"
16+
echo " log show --last 10m --predicate 'process == \"Swach\"'"
17+
echo ""
18+
echo "To export to file:"
19+
echo " log show --last 10m --predicate 'process == \"Swach\"' > ~/Desktop/swach-logs.txt"

0 commit comments

Comments
 (0)