GUIDES Optimizing Embedded JavaScript Reducing Stack Use
About
Binary Data
Index
Convert String to ArrayBuffer
Convert ArrayBuffer to String
Convert ArrayBuffers to String
Handle Errors Converting ArrayBuffer to String
Immutable ArrayBuffers
Resize an ArrayBuffer
Combine ArrayBuffers
Convert Base64 to Binary Data
Convert Binary Data to Base64
Convert Binary Data to Hex
Convert Hex to Binary Data
Calculate CRC for Binary Data
Compress Binary Data – One Buffer
Compress Binary Data – Streaming
Decompress Binary Data – One Buffer
Decompress Binary Data – Streaming
Callbacks
Index
One-Time Callback
Repeating Callback
Repeating Callback with Initial Delay
Immediate Callback
Reschedule Callback
Cancel Callback
Suspend Callback
What About setTimeout?
Optimizing Embedded JavaScript
Index
When to Optimize
Know Where to Optimize
Looping through an Array
Iterating Over a String
Building a String
Avoid Copying Buffers
Accessing Properties
Map versus Object
Appending to an Array
Operating on Bits
Defining Class Methods
Reducing Stack Use
Time
Index
Get Unix Time
Get Time of Day
Get Date
Get Time Since System Start
Get Microseconds
Set System Date and Time
Set Real-Time Clock Time
Get Time and Date from Network
Get Time and Date from Real-Time Clock
Sleep

Reducing Stack Use

The JavaScript stack is another resource that may be optimized. The default JavaScript stack size is just 4 KB on many embedded systems and seldom more than 8 KB. You can adjust the stack size in the creation section of your project's manifest. But, naturally, memory reserved for the stack is unavailable for other purposes. Eventually, you may need to optimize your stack use.

Each function call uses space on the stack, for function arguments, local variables, and the JavaScript stack frame. Eliminating nested function calls always helps. Sometimes those function calls are a bit hidden in JavaScript syntax. For example, this use of forEach adds two stack frames, one for the call to forEach and another to call the arrow function. Both can be eliminated at the cost of a local variable.

/* BEFORE */
let total = 0;
array.forEach(value => total += value)

/* AFTER */
let total = 0;
for (let i = 0; i < array.length; i++)
	total += array[i];

If your function exists by returning the value of another function, you can benefit from tail call optimizations (TCO). This eliminates the stack frame of the calling function before calling the final function. Normally, tail call optimizations are used to minimize the stack use of deep recursion. TCO is also an effective technique for eliminating unnecessary stack frames in non-recursive code.

// No tail call optimization
function negativeMin(a, b) {
	let c = Max.min(-a, -b);
	return c;
}

// Tail call optimization
function negativeMin(a, b) {
	return Max.min(-a, -b);
}

If you are unsure about your code's stack use, the xsbug debugger can help. Use the Instruments pane to monitor stack use. The value is updated in real-time as you step through the code.