Skip to content

Commit d49fa58

Browse files
committed
perf(desktop): shrink browser panel snapshots
1 parent 7c146c6 commit d49fa58

1 file changed

Lines changed: 24 additions & 1 deletion

File tree

  • apps/desktop/src/main/browser-agent

apps/desktop/src/main/browser-agent/panel.ts

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,23 @@ function resetOcclusion(): void {
283283
* the one caller that captures an already-hidden page (a tab switched while the
284284
* panel is occluded), where it stops Chromium promoting it back for the shot.
285285
*/
286+
/** Widest the placeholder snapshot needs to be; it sits behind a transient overlay. */
287+
const SNAPSHOT_MAX_WIDTH = 1024
288+
const SNAPSHOT_JPEG_QUALITY = 70
289+
290+
/**
291+
* Turns a captured frame into a compact JPEG data URL. Resize is a native
292+
* operation and JPEG encode runs in native code too, so both are far cheaper
293+
* than a full-resolution PNG `toDataURL`, which encodes synchronously on the
294+
* event loop.
295+
*/
296+
function encodeSnapshot(image: Electron.NativeImage): string {
297+
const { width } = image.getSize()
298+
const scaled = width > SNAPSHOT_MAX_WIDTH ? image.resize({ width: SNAPSHOT_MAX_WIDTH }) : image
299+
const jpeg = scaled.toJPEG(SNAPSHOT_JPEG_QUALITY)
300+
return `data:image/jpeg;base64,${jpeg.toString('base64')}`
301+
}
302+
286303
function capturePanelSnapshot(onSettled?: () => void): void {
287304
const active = host.activeTab()
288305
const win = panelWindow()
@@ -301,7 +318,13 @@ function capturePanelSnapshot(onSettled?: () => void): void {
301318
// picture of the page, so it goes to the window still showing the
302319
// browser or nowhere at all.
303320
if (panelWindow() !== win || win.isDestroyed()) return
304-
const snapshot: BrowserPanelSnapshot = { dataUrl: image.toDataURL(), tabId }
321+
// Downscale and JPEG-encode before crossing IPC. capturePage returns a
322+
// device-pixel PNG — on a retina half-window that is millions of pixels,
323+
// and toDataURL's PNG encode is synchronous on the main process, so a
324+
// full-size encode stalls every window's input for the frame. This is a
325+
// placeholder shown under a transient overlay, so a downscaled JPEG is
326+
// indistinguishable and an order of magnitude cheaper to encode and send.
327+
const snapshot: BrowserPanelSnapshot = { dataUrl: encodeSnapshot(image), tabId }
305328
win.webContents.send('browser-agent:panel-snapshot', snapshot)
306329
})
307330
.catch((error) => {

0 commit comments

Comments
 (0)