High-Performance Geometric Computation in Electron and React

The development of professional-grade desktop applications for geometric modeling, CAD, and additive manufacturing requires a sophisticated synthesis of high-performance WebAssembly (WASM) computational kernels and highly responsive user interfaces. In the context of Electron and React, the fundamental challenge arises from the single-threaded nature of the JavaScript environment. When performing intensive Constructive Solid Geometry (CSG) operations, such as those provided by the Manifold 3D library, the execution of complex Boolean unions, intersections, or mesh repairs can saturate the CPU for durations exceeding thirty seconds.1 Without a robust architectural strategy for concurrency and memory management, these operations inevitably block the main renderer thread, leading to visual stagnation, input latency, and a degraded user experience. This report details the technical strategies required to offload these computations, optimize data sharing through zero-copy mechanisms, and maintain a fluid UI through React’s concurrent rendering features and dedicated computation managers.

Concurrency Models in the Electron Ecosystem

Electron’s architecture is inherently multi-process, consisting of a single Main process and one or more Renderer processes. For applications performing heavy geometric computation, the distribution of work across these processes—and their internal threads—is the primary lever for maintaining responsiveness. While the Renderer process is responsible for the React-based UI and the Three.js render loop, it is often necessary to spawn additional execution contexts to handle the “heavy lifting” of Manifold WASM.2

Comparison of Execution Contexts for Compute-Heavy Tasks

The selection of a concurrency primitive depends on the required API access, memory isolation, and communication overhead. Developers must evaluate the trade-offs between Web Workers, Node.js worker_threads, and hidden BrowserWindow instances.

 

Technology Process/Thread Context API Access Shared Memory Support Optimal Use Case
Web Workers Thread within Renderer Web APIs, limited Node.js SharedArrayBuffer, Transferables CSG operations and geometry processing 2
worker_threads Thread within Main/Renderer Full Node.js APIs, no DOM SharedArrayBuffer, Transferables I/O-heavy tasks or native Node.js module integration 3
BrowserWindow Separate OS Process Full Web + Node.js APIs IPC only (Serialized) Complex UI-bound sub-apps or high-risk sandbox tasks 5
Child Processes Separate OS Process OS-level, system shell IPC / Named Pipes Multi-core parallelism for external CLI tools 7

Web Workers are typically the preferred choice for geometric modeling in the browser environment because they are natively supported by modern 3D libraries and offer the most efficient path for transferring large buffers of vertex and index data.2 Electron provides a specialized configuration, nodeIntegrationInWorker, which allows these workers to access Node.js modules if required, though this must be balanced against the thread-safety of the modules being loaded.4

Multi-Process Communication Patterns

In a standard geometric application, the Renderer process hosts the Three.js scene. When a Boolean operation is requested, the application must communicate this to a worker. This involves serializing the request and transferring the underlying mesh data. Electron’s architecture facilitates this through IPC (Inter-Process Communication) when moving between Main and Renderer, but for worker-level tasks, the standard Web Worker postMessage API is used. The “Main Thread” in this report’s context refers to the Renderer’s UI thread, where the React state and Three.js loop reside.5

Web Worker Architecture and Data Transfer Optimization

The core of the solution for offloading Manifold WASM operations is a dedicated Web Worker architecture. Manifold 3D, compiled to WASM via Emscripten, provides a robust C++ kernel for manifold mesh operations, but its serial execution model means that a single union operation on high-polygon meshes can completely halt the event loop.1

The Structured Clone Bottleneck

By default, data sent via postMessage is copied using the structured clone algorithm. For a 3D mesh consisting of triangles, the vertex positions, normals, and indices can easily occupy several hundred megabytes. Copying this data across the thread boundary is an operation that can take hundreds of milliseconds, effectively creating a “mini-freeze” every time a task is offloaded or returned.8

Leveraging Transferable Objects for Zero-Copy Movement

To eliminate the copying overhead, developers must utilize Transferable objects. The ArrayBuffer underlying a Three.js BufferAttribute is transferable.8 When an ArrayBuffer is transferred, the memory is “neutered” in the sending thread and instantly becomes available in the receiving thread. This is a constant-time operation that involves only the transfer of memory ownership, not the bytes themselves.12

Implementation Strategy for Three.js Geometry

To transfer a THREE.BufferGeometry to a worker for a Manifold Boolean operation, the following pattern is employed:

  1. Extract the TypedArray from each BufferAttribute (e.g., position, normal, index).
  2. Pass the underlying buffer of these arrays into the postMessage transfer list.
  3. In the worker, reconstruct the geometry or convert it directly into Manifold’s internal mesh format.2

 

JavaScript

 

// Main Thread: Offloading a mesh to the worker
const positionBuffer = geometry.getAttribute(‘position’).array.buffer;
const indexBuffer = geometry.index.array.buffer;

worker.postMessage({
  type: ‘BOOLEAN_UNION’,
  data: { positions: positionBuffer, indices: indexBuffer }
},); // Transfer ownership here

Upon completion, the worker performs a similar transfer to return the result. This ensures that the UI thread is only blocked for the negligible time it takes to re-link the memory to a new BufferAttribute.2

SharedArrayBuffer and Cross-Origin Isolation

While Transferables are highly efficient, they are destructive—the sender loses access to the data. In complex geometric workflows where multiple workers may need to read the same base geometry simultaneously, or where the UI needs to maintain a read-only copy of the mesh for raycasting, SharedArrayBuffer (SAB) provides a superior alternative.13

Mechanism of Shared Memory in Electron

SharedArrayBuffer allows multiple agents (the main thread and workers) to read and write to the same memory segment simultaneously. This is the ultimate “zero-copy” strategy, as no transfer or ownership change is required. To prevent race conditions, JavaScript provides the Atomics object, allowing for thread-safe operations like Atomics.add or Atomics.wait.13

Security and Isolation Requirements

Due to historical vulnerabilities like Spectre and Meltdown, SharedArrayBuffer is gated behind a security requirement known as “Cross-Origin Isolation”.16 In a web environment, this requires the server to send specific headers. In Electron, this must be configured in the Main process using the session.webRequest API to intercept and modify the headers of the application’s responses.18

COOP and COEP Configuration

To enable SAB, the application must set the following headers:

  • Cross-Origin-Opener-Policy: same-origin
  • Cross-Origin-Embedder-Policy: require-corp

 

JavaScript

 

// Electron Main Process: Enabling SharedArrayBuffer
const { session } = require(‘electron’);

session.defaultSession.webRequest.onHeadersReceived((details, callback) => {
  callback({
    responseHeaders: {
    …details.responseHeaders,
      ‘Cross-Origin-Opener-Policy’: [‘same-origin’],
      ‘Cross-Origin-Embedder-Policy’: [‘require-corp’]
    }
  });
});

With these headers, self.crossOriginIsolated will return true, allowing the creation and sharing of SharedArrayBuffer instances.16 This architecture is particularly powerful for Manifold WASM if the module is compiled with multi-threading enabled (-pthread), as the WASM linear memory itself can be backed by an SAB, allowing the C++ kernel to use its own internal threads via std::thread or TBB.20

Decoupled Rendering with OffscreenCanvas

A significant source of UI jank in 3D applications is the “buffer upload” phase. Even if computation is offloaded, the main thread must still upload the resulting millions of vertices to the GPU, which can take several frames. Furthermore, if the application needs to maintain 60 FPS animations (e.g., a spinning progress indicator or a camera fly-through) while the geometry is being processed, the main thread may be too busy to render.22

Architectural Decoupling

OffscreenCanvas allows a worker thread to take control of a <canvas> element. By calling canvas.transferControlToOffscreen(), the main thread hands over the WebGL context to a worker.24 This worker runs its own requestAnimationFrame loop, entirely independent of the main thread’s activity.22

Benefits for Geometric Computation

  1. Render Isolation: Even if the React main thread is busy with complex DOM updates or heavy reconciliation, the 3D scene remains fluid.22
  2. Parallelization: The worker can perform both the geometric computation and the rendering update locally, avoiding any main-thread synchronization until the user needs to interact with the UI.22
  3. Frame Stability: High-frequency animations inside the 3D view are no longer susceptible to main-thread garbage collection pauses or event loop delays.22

 

Context Responsibility Interaction Pattern
Main Thread (React) UI Logic, Inputs, Menus React Concurrent Mode / startTransition 27
Compute Worker Manifold CSG, Mesh Logic Shared Memory / Transferables 2
Render Worker Three.js Loop, Shaders OffscreenCanvas, requestAnimationFrame 22

In this “Triple-Thread” architecture, the application remains responsive even during a 30-second Boolean operation. The UI is handled by Thread A, the computation by Thread B, and the visualization of the “work-in-progress” or existing scene by Thread C.21

Progress Reporting from WASM Operations

A critical usability requirement is providing the user with progress feedback during long operations. However, WebAssembly modules compiled from C++ are often “atomic” from the perspective of JavaScript; once called, the module does not return control until the task is complete.1

Manifold’s Execution Model

Manifold 3D operations are generally serial in their WASM build.1 To report progress, the developer must find a way to make the C++ code “yield” to the environment.

Strategies for Incremental Feedback

  1. Asyncify: This Emscripten feature allows C++ code to pause and return control to the JavaScript event loop (e.g., by calling emscripten_sleep(0)).29 If the Manifold kernel is modified to call a progress function that sleeps periodically, the worker can use postMessage to report its status to the main thread.20
  2. Sub-operation Forcing: Boolean operations in Manifold can be lazy. Calculations are often not finalized until a property like getMesh() or genus() is requested.1 By breaking a massive Boolean task (e.g., 100 unions) into smaller batches of 5 and requesting the mesh at each step, the developer can manually report progress (e.g., “5% complete”) between batches.1
  3. Pipeline Stage Callbacks: Other libraries implement callbacks for specific stages such as GeneratingVerts or SolvingQef.30 While Manifold’s core is less verbose, wrapping the Manifold calls in a JavaScript loop that handles spatial partitioning (octrees) allows for incremental progress as each leaf of the octree is processed.1

React Concurrent Mode and startTransition

React 18’s concurrent features provide the final layer of UI responsiveness by ensuring that the “urgent” user interactions (like typing in a text field or clicking a button) are not blocked by “non-urgent” updates (like re-rendering the 3D view state).27

Priority Scheduling with useTransition

When a geometric operation is initiated, it often triggers a global state change that causes many components to re-render. If this update is synchronous, the UI will freeze. By using the useTransition hook, the developer can mark the geometry update as a “transition”.27

 

JavaScript

 

const = useTransition();

const handleBooleanUnion = () => {
  // Marking the heavy state update as non-urgent
  startTransition(() => {
    dispatch({ type: ‘START_CSG_OP’ });
    computationManager.submit(‘UNION’, meshData);
  });
};

During the transition, React continues to handle high-priority events like animations and input. If the user decides to cancel the operation while React is still processing the state change, React can interrupt the non-urgent work and switch to the new state immediately.27 This prevents the “laggy” feeling where clicking a button results in a delayed response.

useDeferredValue for Heavy Visualization Components

For components that render complex data (like a tree of mesh metadata), useDeferredValue can be used to provide a stale version of the UI while the worker is computing the new version. This ensures that the UI remains interactive even if the data being displayed is several seconds old.35

Practical Implementation: The Computation Manager Pattern

A “Computation Manager” is a central architectural component that orchestrates the lifecycle of geometric tasks. It acts as a bridge between the React UI and the Web Worker pool, providing features like queuing, prioritization, and cancellation.2

Queuing and Prioritization

Not all geometric operations are equal. A “mesh loading” task might be more urgent than an “offline hole-filling” task. The manager maintains a priority queue:

  • Priority 1 (Interactive): Decimation for preview, raycasting, selection.
  • Priority 2 (Standard): Booleans, repairs.
  • Priority 3 (Batch): Exporting high-res models.2

The manager ensures that only a limited number of workers (typically navigator.hardwareConcurrency) are active to avoid system-wide slowdowns.3

Cancellation and AbortController

Canceling a long-running WASM operation is notoriously difficult because a worker cannot be “interrupted” without being terminated. The Computation Manager provides two methods:

  1. Hard Termination: Calling worker.terminate().3 This is the only way to stop a runaway WASM loop, but it requires the worker and WASM module to be re-initialized, which incurs a “cold start” penalty of several seconds.28
  2. Soft Cancellation (Shared State): By using a SharedArrayBuffer with an “abort flag,” the worker can check periodically (if the code supports it) whether it should continue. This allows for clean exits and memory cleanup.20

Computation Manager Architecture Diagram

<— useTransition —> [ Computation Manager ]

|

|

| | |

[ Queue: Priority ]

| | |

<— Transferables —> <— SAB —>

React+Electron Code Example: Computation Manager Integration

 

TypeScript

 

// useComputationManager.ts
import { useState, useTransition, useCallback } from ‘react’;

export function useGeometryTask() {
  const = useTransition();
  const = useState(null);

  const runTask = useCallback((type, geometry) => {
    const manager = getGlobalComputationManager();
   
    // UI remains responsive during this trigger
    startTransition(async () => {
      try {
        const meshData = await manager.request(type, {
          positions: geometry.attributes.position.array.buffer,
          indices: geometry.index.array.buffer
        });
        setResult(meshData);
      } catch (err) {
        console.error(“Task failed or was cancelled”, err);
      }
    });
  },);

  return { runTask, result, isPending };
}

Chunked and Incremental Processing Strategies

For massive meshes (exceeding triangles), even offloading to a worker may not be enough to prevent a perceptible “hitch” when the results are returned. Incrementalism is the strategy of breaking these large tasks into chunks that fit within the requestAnimationFrame (rAF) budget.27

Spatial Subdivision for Parallel Booleans

A large mesh can be subdivided into spatial chunks using an Octree or BVH (Bounding Volume Hierarchy).39 When performing a Boolean union, the Computation Manager can:

  1. Identify which chunks are “affected” by the operation (those intersecting the other mesh’s bounding box).
  2. Perform Boolean operations only on these specific chunks in parallel workers.1
  3. Re-stitch the modified chunks back into the main mesh.41

Incremental Mesh Reconstruction

When returning data from the worker, the manager can send back chunks of the mesh (e.g., 100,000 triangles at a time).32 The main thread uses requestAnimationFrame to add these chunks to the Three.js scene over several frames. This prevents a large “Buffer Upload” freeze and allows the user to see the mesh being “built” in real-time.42

Conclusion and Strategic Outlook

Preventing UI freezes in Electron applications performing heavy geometric computation requires a multi-faceted approach that spans the entire stack, from lower-level memory management to high-level UI orchestration. The transition from monolithic, single-threaded processing to a decoupled, multi-worker architecture is the most significant step. By utilizing Web Workers for offloading and Transferable objects for efficient data movement, developers can eliminate the primary source of UI blocking.2

The adoption of SharedArrayBuffer and Cross-Origin Isolation provides a path toward zero-copy interaction, which is essential for the next generation of high-resolution 3D applications.14 Paired with OffscreenCanvas, these technologies allow the 3D rendering loop to remain fluid regardless of the main thread’s workload.22 At the application level, React’s concurrent rendering and the “Computation Manager” pattern provide the necessary control to prioritize user interactions and manage task lifecycles gracefully.2

As libraries like Manifold 3D continue to evolve their WASM builds, and as WebAssembly gains more native multi-threading capabilities, the gap between desktop-native and Electron-based geometric modeling will continue to narrow. The strategies outlined in this report provide the technical foundation for building high-performance, responsive, and robust geometric modeling applications in the modern web ecosystem.

Works cited

  1. WASM questions (JS in browser) · elalish manifold · Discussion …, accessed April 16, 2026, https://github.com/elalish/manifold/discussions/256
  2. Web Workers – Gridfinity Builder – Mintlify, accessed April 16, 2026, https://www.mintlify.com/tunelko/gridfinity-BambuLab-3D/architecture/web-workers
  3. Worker Threads and Web Workers | by Rahul Jindal – Medium, accessed April 16, 2026, https://medium.com/@rahul.jindal57/worker-threads-and-web-workers-a-detailed-explanation-16152aa77996
  4. Multithreading | Electron, accessed April 16, 2026, https://electronjs.org/docs/latest/tutorial/multithreading
  5. Performance | Electron, accessed April 16, 2026, https://electronjs.org/docs/latest/tutorial/performance
  6. Electron multithreading best practice question : r/electronjs – Reddit, accessed April 16, 2026, https://www.reddit.com/r/electronjs/comments/6u3mx2/electron_multithreading_best_practice_question/
  7. Does the electron framework allow multi-threading through web workers? – Stack Overflow, accessed April 16, 2026, https://stackoverflow.com/questions/36942555/does-the-electron-framework-allow-multi-threading-through-web-workers
  8. How to handle THREE.Mesh objects in a worker – Stack Overflow, accessed April 16, 2026, https://stackoverflow.com/questions/37347037/how-to-handle-three-mesh-objects-in-a-worker
  9. A bare minimal example of a Web Worker running in Electron with Node integration enabled. – GitHub, accessed April 16, 2026, https://github.com/trusktr/electron-web-worker-example
  10. How I squeezed out 80% UI speed gains using Web Workers in my Electron app, accessed April 16, 2026, https://javascript.plainenglish.io/how-i-squeezed-out-80-ui-speed-gains-using-web-workers-in-my-electron-app-9fe4e7731e7d
  11. elalish/manifold: Geometry library for topological robustness – GitHub, accessed April 16, 2026, https://github.com/elalish/manifold
  12. Transferable objects – Web APIs | MDN, accessed April 16, 2026, https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Transferable_objects
  13. SharedArrayBuffer – JavaScript – MDN Web Docs, accessed April 16, 2026, https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer
  14. SharedArrayBuffer: The Hidden Super-Primitive That’s Reshaping the Future of WebAssembly, .NET & Parallel Runtime Architecture | by Jacob Mellor | Medium, accessed April 16, 2026, https://medium.com/@jacobscottmellor/sharedarraybuffer-the-hidden-super-primitive-thats-reshaping-the-future-of-webassembly-net-e369e667f6e9
  15. About SharedArrayBuffer & Atomics | by Andrea Giammarchi – Medium, accessed April 16, 2026, https://webreflection.medium.com/about-sharedarraybuffer-atomics-87f97ddfc098
  16. A guide to enable cross-origin isolation | Articles – web.dev, accessed April 16, 2026, https://web.dev/articles/cross-origin-isolation-guide
  17. Understanding SharedArrayBuffer and cross-origin isolation – LogRocket Blog, accessed April 16, 2026, https://blog.logrocket.com/understanding-sharedarraybuffer-and-cross-origin-isolation/
  18. Security | Electron, accessed April 16, 2026, https://www.electronjs.org/docs/latest/tutorial/security#17-configure-the-cross-origin-embedder-policy-and-cross-origin-opener-policy-headers
  19. COOP and COEP explained – Google Docs, accessed April 16, 2026, https://docs.google.com/document/d/1zDlfvfTJ_9e8Jdc8ehuV4zMEu9ySMCiTGMS9y0GU92k/edit
  20. “Enabling” C threads in a Python / Wasm environment, accessed April 16, 2026, https://yosefk.com/blog/enabling-c-threads-in-a-python-wasm-environment.html
  21. Multithread Support with Emscripten · jrouwe JoltPhysics.js · Discussion #110 – GitHub, accessed April 16, 2026, https://github.com/jrouwe/JoltPhysics.js/discussions/110
  22. OffscreenCanvas—speed up your canvas operations with a web worker | Articles, accessed April 16, 2026, https://web.dev/articles/offscreen-canvas
  23. Using Web Workers and OffscreenCanvas for Smooth Rendering in JavaScript – Medium, accessed April 16, 2026, https://medium.com/@lightxdesign55/using-web-workers-and-offscreencanvas-for-smooth-rendering-in-javascript-1c9df43fdb52
  24. Examples of chart rendering using offscreen canvas – GitHub, accessed April 16, 2026, https://github.com/chrisprice/offscreen-canvas
  25. OffscreenCanvas – Web APIs | MDN, accessed April 16, 2026, https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas
  26. Enhancing Graphics Performance with OffscreenCanvas and D3.js – DEV Community, accessed April 16, 2026, https://dev.to/jeevankishore/enhancing-graphics-performance-with-offscreencanvas-and-d3js-19ka
  27. Concurrent features – Raw Bits to React – Mintlify, accessed April 16, 2026, https://www.mintlify.com/renderffx/raw-bits-to-react/react/concurrent-features
  28. How to stop a wasm function? – help – The Rust Programming Language Forum, accessed April 16, 2026, https://users.rust-lang.org/t/how-to-stop-a-wasm-function/58672
  29. Emscripten Runtime Environment, accessed April 16, 2026, https://emscripten.org/docs/porting/emscripten-runtime-environment.html
  30. Tessellation — Rust math library // Lib.rs, accessed April 16, 2026, https://lib.rs/crates/tessellation
  31. GitHub – hmeyer/tessellation: Tessellation is a library for 3d tessellation, e.g. it will create a set of triangles from any implicit function of volume., accessed April 16, 2026, https://github.com/hmeyer/tessellation
  32. Proceedings Volume PCaPAC2012, accessed April 16, 2026, https://proceedings.jacow.org/pcapac2012/papers/proceed.pdf
  33. Frontend Handbook | React / Recipes / React Concurrency – Infinum, accessed April 16, 2026, https://infinum.com/handbook/frontend/react/recipes/react-concurrency
  34. Adopting React Concurrent Mode in Production – Medium, accessed April 16, 2026, https://medium.com/@vasanthancomrads/adopting-react-concurrent-mode-in-production-9c37693ca9b0
  35. How to Handle Concurrent Mode in React, accessed April 16, 2026, https://oneuptime.com/blog/post/2026-01-24-handle-concurrent-mode-react/view
  36. Software Defined Networks, accessed April 16, 2026, https://ridhanegara.staff.telkomuniversity.ac.id/files/2017/04/Paul-Goransson-and-Chuck-Black-Auth.-Software-Defined-Networks.-A-Comprehensive-Approach.pdf
  37. realData.csv – GitHub Gist, accessed April 16, 2026, https://gist.github.com/shikhar-scs/0198e189643352e8f2e556f1fdd3217a
  38. Mastering Web Workers in React: Advanced Patterns for Thread-Safe Performance | by Artur, accessed April 16, 2026, https://medium.com/@arturfse/mastering-web-workers-in-react-advanced-patterns-for-thread-safe-performance-4498503c7fb9
  39. three-mesh-bvh – NPM, accessed April 16, 2026, https://www.npmjs.com/package/three-mesh-bvh
  40. GitHub – gkjohnson/three-mesh-bvh: A BVH implementation to speed up raycasting and enable spatial queries against three.js meshes., accessed April 16, 2026, https://github.com/gkjohnson/three-mesh-bvh
  41. Generating 3D Meshes From Text :: Casey Primozic’s Notes, accessed April 16, 2026, https://cprimozic.net/notes/posts/generating-3d-meshes-from-text/
  42. Technologies for 3D mesh compression: A survey – USC Media Communications Lab, accessed April 16, 2026, http://mcl.usc.edu/wp-content/uploads/2014/01/200503-Technologies-for-3D-triangular-mesh-compression-a-survey.pdf
About the Author
RapidMade | High-Performance Geometric Computation in Electron and React

Micah Chaban
Founder & Vice President
RapidMade, Inc.

For 15 years I have worn every hat in our factory. I have advised engineers, fixed 3D printers, and toiled in the shop before we had a single employee. I write technical content for people who make parts that need to work in the real world.

talk out to us!

Call

(503) 943-2781 ext 1

Email

info@rapidmade.com

Chat

Bottom right page corner

Contact
VP of Sales and Marketing

Contact
3D Print Sales Specialist