Context Isolation transition to contextBridge for secure API exposure
0 reputation · 12 Apr 2022, 18:25 UTC
0 reputation · 12 Apr 2022, 18:25 UTC
Electron version 12 and later default to contextIsolation: true to prevent renderer processes from accessing Node.js internals. This security boundary is designed to stop unauthorized public access to system APIs by separating the JavaScript contexts of the preload script and the renderer.
While contextBridge allows the definition of a controlled gateway for specific functions, there is a technical trade-off between the security of serialized communication and the performance overhead introduced when passing large data structures across the bridge.
contextBridge compared to shared state?33775 reputation · 12 Apr 2022, 23:16 UTC
With contextIsolation: true (default since Electron 12), the preload script and renderer run in separate V8 contexts. Every argument and return value crossing contextBridge is structured-cloned, so high-frequency APIs pay a per-call cost that grows with payload size and complexity. Unlike shared state with isolation disabled, there is no zero-copy reference sharing. Functions cannot be cloned, so each exposed method becomes an async trampoline that allocates a promise and a message per call. Per-property access on a bridged object also crosses the boundary, meaning deep object graphs or getter-heavy proxies multiply crossings dramatically.
| Item | Status | Notes |
|---|---|---|
| Values cross via structured clone | Confirmed | Applies to all arguments and return values through contextBridge. |
| Class instances lose prototypes | Confirmed | They arrive as plain objects; Error stacks are also lost. |
| Functions are not cloneable | Confirmed | Exposed methods are async wrappers, not direct references. |
| Exact per-call millisecond cost | Uncertain | Varies by Electron version, V8 version, and payload shape; measure on your target version. |
| ArrayBuffer copy versus transfer | Uncertain | Behavior is version-sensitive; do not assume zero-copy without benchmarking. |
ArrayBuffer or TypedArray over deeply nested plain-object trees, and avoid re-wrapping data on every update.contextIsolation: false or nodeIntegration: true to remove the boundary.Build a minimal app with contextIsolation: true and time N round-trips using performance.now(), comparing a small object against a 10,000-element array. Record a Chrome DevTools performance trace on the high-frequency path to check whether serialization blocks the renderer main thread. Compare a fine-grained bridged proxy against one batched method returning a single object to quantify per-crossing overhead.
Missing diagnostic detail: What Electron version are you targeting? ArrayBuffer transfer semantics and preload sandbox behavior differ across versions, and that determines whether binary transfer is a safe optimization for your case.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.