JavaScriptPerformanceWebAssemblyMultithreadingSharedArrayBuffer

Typed Arrays & Shared Memory: Ultra-Fast JavaScript

P
Performance Engineer
Featured Guide 22 min read

Stop Copying Data.

Normally, sending data to a Web Worker involves cloning it (Structured Clone Algorithm). This is slow for large datasets.

SharedArrayBuffer allows the Main Thread and Worker Threads to read/write the exact same memory address. Zero copy.

Deep Dive: Generic Security Headers

To use SharedArrayBuffer, your server must send strict security headers to prevent Spectre/Meltdown attacks:

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

Without these, the browser will not define SharedArrayBuffer on the window object.

02. Raw Memory Access

We allocate a chunk of raw binary memory. Then we "view" it as an array of 32-bit Integers.

// main.js
const
buffer =
new
SharedArrayBuffer(1024); // 1KB
const
view =
new
Int32Array(buffer);

// Send REF to worker
worker.postMessage(buffer);

03. Race Conditions & Atomics

When two threads write to index 0 at the same time, you get garbage data. Use Atomics to lock memory during operations.

Atomics.add(view, 0, 1); // Thread-safe increment

Deep Dive: Compare-Exchange

The holy grail of concurrency is Atomics.compareExchange(view, index, oldVal, newVal).

It says: "Only update this memory if it currently equals oldVal." This instruction is atomic at the CPU hardware level and is used to build Mutexes and Semaphores in JS.

04. The Senior Engineer's Take

You probably need Wasm.

If you are manually manipulating bytes in JavaScript to squeeze performance, you should likely be writing Rust compiled to WebAssembly.

Rust handles memory safety for you. Raw TypedArrays are tedious and error-prone.

Interactive Playground

import React, { useState, useEffect } from 'react';

// 🧠 Shared Memory Visualizer

export default function MemoryDemo() {
    const [memory, setMemory] = useState(new Array(8).fill(0));
    const [isSharing, setIsSharing] = useState(false);
    
    // Simulate workers writing to memory
    useEffect(() => {
        if (!isSharing) {
            setMemory(new Array(8).fill(0));
            return;
        }

        const interval = setInterval(() => {
            setMemory(prev => {
                const next = [...prev];
                // Randomly increment a slot (simulating thread activity)
                const idx = Math.floor(Math.random() * 8);
                if (next[idx] < 99) next[idx] += 1;
                return next;
            });
        }, 100);

        return () => clearInterval(interval);
    }, [isSharing]);

    return (
        <div className="bg-slate-50 dark:bg-slate-950 p-8 rounded-3xl border border-slate-200 dark:border-slate-800 shadow-xl">
             <div className="flex justify-between items-center mb-10">
                <h3 className="text-2xl font-black text-gray-900 dark:text-white flex items-center gap-3">
                    <span className="text-cyan-500">🧠</span> Shared Memory
                </h3>
                <button 
                    onClick={() => setIsSharing(!isSharing)}
                    className={`px-6 py-2 rounded-lg font-bold text-sm transition-all ${isSharing ? 'bg-red-500 text-white' : 'bg-cyan-500 text-white'}`}
                >
                    {isSharing ? 'Stop Workers' : 'Start Threads'}
                </button>
            </div>

            <div className="flex flex-col md:flex-row gap-12">
                
                {/* Threads */}
                <div className="space-y-4 w-full md:w-1/3">
                     <div className="p-4 bg-white dark:bg-slate-900 rounded-xl border border-slate-200 dark:border-slate-800 shadow flex items-center gap-3 opacity-50">
                        <span>💻</span> Main Thread (UI)
                     </div>
                     <div className={`p-4 bg-white dark:bg-slate-900 rounded-xl border border-slate-200 dark:border-slate-800 shadow flex items-center gap-3 transition-all ${isSharing ? 'border-cyan-500 shadow-[0_0_15px_rgba(6,182,212,0.3)]' : ''}`}>
                        <span className={isSharing ? "text-cyan-500" : "text-gray-400"}></span> Worker Thread 1
                     </div>
                     <div className={`p-4 bg-white dark:bg-slate-900 rounded-xl border border-slate-200 dark:border-slate-800 shadow flex items-center gap-3 transition-all ${isSharing ? 'border-purple-500 shadow-[0_0_15px_rgba(168,85,247,0.3)]' : ''}`}>
                        <span className={isSharing ? "text-purple-500" : "text-gray-400"}></span> Worker Thread 2
                     </div>
                </div>

                {/* The Shared Buffer */}
                <div className="flex-1 bg-slate-200 dark:bg-slate-900 rounded-2xl p-6 relative">
                     <div className="absolute -top-3 left-6 px-2 bg-slate-50 dark:bg-slate-950 text-xs font-bold text-gray-500 uppercase tracking-widest border border-slate-200 dark:border-slate-800 rounded">
                         SharedArrayBuffer (Int32Array View)
                     </div>
                     
                     <div className="grid grid-cols-4 gap-4 mt-4">
                         {memory.map((val, i) => (
                             <div 
                                key={i}
                                className={`aspect-square rounded-lg flex items-center justify-center font-mono text-xl font-bold transition-all duration-75 ${
                                    val > 0 
                                    ? 'bg-cyan-500 text-white scale-105 shadow-lg' 
                                    : 'bg-white dark:bg-slate-800 text-gray-300'
                                }`}
                             >
                                 {val}
                             </div>
                         ))}
                     </div>
                     
                     {isSharing && (
                         <div className="absolute inset-0 border-2 border-dashed border-cyan-500/30 rounded-2xl animate-pulse pointer-events-none"></div>
                     )}
                </div>

            </div>
        </div>
    );
}