Gonzalo Galante Logo
RECORD_DETAILS_v1.0

WebGL vs WebGPU: The Performance Gap

Published: Jan 22, 2026
Reading Time: ~5 min
Ref_ID:webgl-vs

Why Your Browser is Choking on 3D (And How to Fix It)

I remember the first time I tried to render 10,000 interactive cubes in the browser using standard React Three Fiber. My MacBook Pro's fans spun up like a jet engine, and the frame rate tanked to a cinematic 12 FPS. The CPU was screaming.

For years, we've accepted this bottleneck. We optimized by reducing geometry, baking lighting, or strictly limiting interactivity. We treated the browser like a second-class citizen for 3D graphics.

But the game has changed.

I recently built a side-by-side experiment comparing a naive WebGL implementation against a modern WebGPU approach using Three.js and TSL (Three Shading Language). The difference wasn't just incremental; it was a generational leap. We are talking about moving from 15,000 objects at 15 FPS to 200,000 objects at a locked 60 FPS, all while the CPU usage dropped from 100% to near zero.

Here is what I learned about the shift from the Main Thread to the GPU, and why you need to start caring about TSL today.


The Problem: The CPU Bottleneck

In the traditional WebGL workflow (and specifically within the React ecosystem), we often fall into the trap of "Declarative Thinking". We treat 3D objects like DOM elements.

In my experiment, the WebGL mode did exactly this. I created a <mesh /> component for every single cube and used a loop to update its rotation every frame.

// The "Naive" WebGL Approach
useFrame((state, delta) => {
  // This runs on the CPU, 60 times a second, for EVERY object.
  // 10,000 objects = 600,000 function calls per second.
  ref.current.rotation.x += delta;
});

Why this fails:

  1. Serialization Overhead: JavaScript has to calculate the new matrix for every object.
  2. Bus Saturation: The CPU has to send that updated data to the GPU every single frame.
  3. Single Thread: The browser's main thread is already busy handling React renders, DOM updates, and event listeners.

The result? The GPU is sitting there, bored, waiting for the CPU to finish its math homework.

The Solution: WebGPU and TSL

WebGPU isn't just "WebGL 3.0". It's a fundamental architectural shift that gives us low-level access to the graphics card, similar to Vulkan or Metal. But the real magic capability in Three.js is TSL (Three Shading Language).

TSL allows us to write shader logic using standard JavaScript/TypeScript syntax, which Three.js compiles into WGSL (WebGPU Shading Language). This means we can define the behavior of our objects and ship it directly to the GPU.

In the WebGPU mode of my experiment, I used a single InstancedMesh. But instead of updating the matrix in a JS loop, I defined the position and rotation as Nodes.

// The WebGPU + TSL Approach
import { time, instanceIndex, hash, vec3 } from 'three/tsl';

// Logic defined ONCE, runs purely on the GPU
const index = instanceIndex;
const seed = float(index).mul(0.123);
const t = time.mul(1.0);

// Procedural rotation calculated in the Vertex Shader
const angle = t.add(seed).mul(2.0);
const rotatedPos = rotateVector(positionLocal, axis, angle);

// No CPU update loop. 0% Main Thread usage.
material.positionNode = offset.add(rotatedPos);

The Impact:

  • Zero CPU Usage: Once the shader is compiled and the buffers are loaded, the CPU does nothing. It just tells the GPU "Draw this again".
  • Massive Scalability: I pushed the slider to 200,000 cubes. The frame rate stayed locked. The bottleneck shifted from "Scripting" (CPU) to "Fill Rate" (GPU pixels), which is exactly where you want it to be.

Technical Benchmark: "The Cube Storm"

I ran this test on a standard M3 MacBook Pro.

MetricWebGL (CPU Bound)WebGPU (TSL Driven)
Object Count15,000 (Max stable)200,000+
FPS~20-30 FPS60 FPS (Locked)
CPU Usage98% (Main Thread blocked)< 2% (Idle)
BottleneckJavaScript ExecutionGPU Fill Rate

The difference is stark. In the WebGL version, the UI becomes unresponsive because the main thread is choked. In the WebGPU version, you can interact with the UI freely because the animation logic is detached from the JavaScript runtime.

Strategic Takeaway

If you are building data visualizations, digital twins, or immersive experiences for the web in 2026, you cannot afford to ignore WebGPU.

  1. Stop animating via CPU: If you are using useFrame to update positions of static geometry, you are doing it wrong.
  2. Embrace Instancing: Draw calls are expensive. Group your geometry.
  3. Learn TSL: It is the bridge that lets frontend developers write high-performance shader logic without learning a new syntax like GLSL or WGSL.

The browser is no longer the limit. Your architecture is.

It is time to let the GPU do the heavy lifting.

Related Records

Log_01Feb 9, 2026

The Brand Alchemist: Decoding the Agentic Shift with Google Pomelli

Google Labs and DeepMind's Pomelli is more than a marketing tool—it's an early look at Agentic Identity. By extracting a brand's Business DNA from a URL and integrating with Veo 3.1, it enables autonomous, on-brand content scaling at an unprecedented level.

Log_02Feb 9, 2026

Engineering Velocity: The Impact of Gemini-CLI on Productivity

A CTO's analysis of why terminal-native AI is replacing chatbots for high-signal engineering work.