Skip to Content
Course content

239: Introduction to TypedArrays

Click on the "Edit" button in the top corner of the screen to edit your slide content.

A few years back, I was mentoring a developer who was trying to build a custom image filter in the browser. He had loaded a raw image file as a massive standard JavaScript array—basically a list of millions of integers representing RGBA values. The result? The browser tab would freeze for three seconds every time he tried to apply a blur, and the memory usage was astronomical. When I looked at his code, I saw he was using a standard [] array. The problem is that standard JS arrays are objects; they're flexible and convenient, but they aren't stored as contiguous blocks of memory. For millions of pixels, that overhead is a performance killer.

This is exactly why TypedArrays exist. When you're dealing with binary data—be it image pixels, audio samples, or network packets—you don't want the "magic" of a standard JavaScript array. You want a raw slab of memory that the CPU can chew through efficiently.

The Slab and the Lens

To understand TypedArrays, you first have to understand the ArrayBuffer. Think of an ArrayBuffer as a raw slab of memory. It's just a sequence of bytes. The catch is that you can't actually manipulate the data inside an ArrayBuffer directly. If you try to access an index on a buffer, you'll get nothing.

To actually read or write to that memory, you need a "View." This is where the TypedArray comes in. A TypedArray is essentially a lens you place over that raw buffer to tell JavaScript how to interpret the bits. Do those 8 bits represent an unsigned integer from 0 to 255? Or does a group of 32 bits represent a floating-point number? You decide by which view you use.

// Create a buffer of 16 bytes
const buffer = new ArrayBuffer(16);

// Create a view that treats the buffer as 8-bit unsigned integers
const uint8View = new Uint8Array(buffer);

// Now we can actually put data in it
uint8View[0] = 255;
uint8View[1] = 128;

console.log(uint8View); // Uint8Array(16) [255, 128, 0, 0, ...]

Choosing Your Precision

Depending on what you're building, you'll pick different TypedArray constructors. I usually categorize them by what I'm trying to achieve. If I'm working with raw file data or colors, Uint8Array (unsigned 8-bit) is the gold standard because it maps perfectly to a single byte.

If I'm doing heavy math or working with WebGL coordinates, I'll reach for Float32Array. If I need to handle larger integers that might be negative, Int32Array is the way to go. The crucial thing to remember is that these arrays are fixed-length. You can't push() or pop() elements like you do with regular arrays. Once you allocate that memory, you're locked in. If you need more space, you have to create a new, larger buffer and copy the data over.

// Let's look at how the same buffer changes based on the view
const sharedBuffer = new ArrayBuffer(4); // 4 bytes total

const view8 = new Uint8Array(sharedBuffer);
const view32 = new Uint32Array(sharedBuffer);

view8[0] = 1;
view8[1] = 0;
view8[2] = 0;
view8[3] = 0;

// Because view32 sees all 4 bytes as one single number, 
// it reads the combined value of those 4 bytes.
console.log(view32[0]); // 1

It's a bit of a mental shift. You stop thinking about "lists of things" and start thinking about "how many bytes does this piece of data actually take up?" It feels lower-level, almost like C, but that's exactly why it's so fast.




📋 Practical Task

Building a Simple RGB-to-Grayscale Buffer Processor

In this exercise, you will simulate a basic image processing task. You'll start with a Uint8Array representing a small 2x2 pixel image (where each pixel has 3 values: Red, Green, and Blue). Your goal is to create a new Uint8Array that converts these colors to grayscale by averaging the RGB values for each pixel.

Requirements:

  • Initialize an ArrayBuffer of 12 bytes (2x2 pixels * 3 channels).
  • Wrap it in a Uint8Array and fill it with some sample RGB values (e.g., [255, 0, 0, 0, 255, 0, 0, 0, 255, 255, 255, 255]).
  • Create a second Uint8Array of the same size to hold the grayscale result.
  • Loop through the original array in increments of 3, calculate the average of the R, G, and B values, and assign that average to all three channels in the result array.
  • Log the final grayscale buffer to the console.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.