Frontend Development 17 min read

Front‑End Memory Management, Data Structures, and Performance Optimization

To handle the massive memory and CPU demands of modern front‑end map annotations, the article explains JavaScript’s stack‑heap model, object hash‑table storage, and the trade‑offs of plain arrays, TypedArray, DataView, and SharedArrayBuffer, showing that contiguous memory structures and Web‑Worker off‑loading dramatically improve performance and reduce allocations.

Amap Tech
Amap Tech
Amap Tech
Front‑End Memory Management, Data Structures, and Performance Optimization

Annotations are a fundamental element of maps, indicating the name of each location or route. In the map JSAPI, the display effect and performance of annotations are critical issues.

The new map annotation design introduces SDF (signed distance field) and moves offset, avoidance, and triangulation calculations to the front‑end, dramatically increasing computation and memory consumption.

For example, rendering ~10,000 text‑bearing annotations in a 3D scene can generate about 2.5 million vertices, requiring roughly 10 MB when stored in a Float32Array .

Because front‑end code now consumes large amounts of memory, the article investigates JavaScript memory structures, starting with the distinction between heap and stack.

Stack memory stores simple data types (numbers, strings, booleans, and references), while heap memory stores complex objects such as Array and Object . Accessing a variable first looks up its address on the stack, then follows that address to the heap.

Object storage in JavaScript uses a hash table. Each property is mapped to a storage address via a hash function. Collisions are resolved using chaining (linked lists). The article lists classic collision‑resolution methods: open addressing, double hashing, and chaining.

Performance tests compare writing to stack‑based variables versus heap‑based objects:

function inStack(){
    let number = 1E5;
    var a;
    while(number--){
        a = 1;
    }
}
var obj = {};
function inHeap(){
    let number = 1E5;
    while(number--){
        obj.key = 1;
    }
}

Results on macOS/Firefox and macOS/Safari show stack writes are faster than heap writes when each function runs 100 000 times.

The article then examines how JavaScript stores objects and arrays. Objects use a hash table; arrays are essentially objects with numeric keys. Different data structures (plain arrays, linked lists, trees) have trade‑offs, and JavaScript chooses hash tables for balanced performance.

Typed arrays ( Int8Array , Int16Array , Float32Array , etc.) provide contiguous memory blocks. Example:

// TypedArray
var typedArray = new Int8Array(10);

typedArray[0] = 8;
typedArray[1] = 127;
typedArray[2] = 128;
typedArray[3] = 256;

console.log("typedArray", "   -- ", typedArray ); // Int8Array(10) [8, 127, -128, 0, 0, 0, 0, 0, 0, 0]

DataView offers more flexible, variable‑length access on top of an ArrayBuffer :

// DataView
var arrayBuffer = new ArrayBuffer(8 * 10);
var dataView = new DataView(arrayBuffer);

dataView.setInt8(0, 2);
dataView.setFloat32(8, 65535);

// Retrieve
dataView.getInt8(0);   // 2
dataView.getFloat32(8); // 65535

Performance comparisons among plain arrays, TypedArray, and DataView show that DataView is slightly slower on Safari and Firefox, but recent V8 optimizations narrow the gap on Chrome.

Shared memory via SharedArrayBuffer enables zero‑copy communication between Web Workers. Example of using postMessage (which clones data) versus shared memory:

// main.js (postMessage)
var worker = new Worker('./worker.js');
worker.onmessage = function(e){
    console.log("e.data", "   -- ", e.data ); // cloned data
    console.log("msg", "   -- ", msg ); // original unchanged
};
var msg = [1,2,3];
worker.postMessage(msg);
// main.js (SharedArrayBuffer)
var worker = new Worker('./sharedArrayBufferWorker.js');
worker.onmessage = function(e){
    console.log("e.data", "   -- ", e.data ); // processed data
    console.log("int8Array-outer", "   -- ", int8Array ); // original mutated
};
var sharedArrayBuffer = new SharedArrayBuffer(3);
var int8Array = new Int8Array(sharedArrayBuffer);
int8Array[0] = 1; int8Array[1] = 2; int8Array[2] = 3;
worker.postMessage(sharedArrayBuffer);
// worker.js (SharedArrayBuffer)
onmessage = function(e){
    var arrayData = increaseData(e.data);
    postMessage(arrayData);
};
function increaseData(arrayData){
    var int8Array = new Int8Array(arrayData);
    for(let i=0;i

Benchmarks show that for 100 k items, shared memory offers little benefit, but at the million‑item scale the performance advantage becomes significant.

The article also briefly covers memory detection (Chrome DevTools Memory panel) and garbage collection strategies, noting that modern browsers use mark‑and‑sweep algorithms to handle cyclic references.

In conclusion, for front‑end projects with massive data (e.g., map annotations), using TypedArray or DataView for contiguous memory, performing heavy calculations in Web Workers, and minimizing temporary allocations can greatly reduce memory consumption and improve performance.

frontendPerformancejavascriptmemory managementTypedArraysharedarraybufferWebWorker
Amap Tech
Written by

Amap Tech

Official Amap technology account showcasing all of Amap's technical innovations.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.