Let's jump into JavaScript VM details to see why and how to guard against this VM de-opt:
🧵🪡🧶
The first thing to understand is that JavaScript has two representations for numbers:
- Integers: Fast path
- Floats (IEEE 754): Slower path
Integers are stored as “Two's complement” and can't have `-0`, but Floats can!
Let's assume: `x` is an Integer and `x = 0`
`0-x` => `0-0 => 0`, Result is `0` (Integer) Perfect!
`-x` => negate `x`.
- For any non-zero value, the result is an Integer.
- But for `0`, the result is `-0`. But integers can't have `-0`, So JavaScript stores it as a Float `-0`.
Why is this a de-opt:
1) Array access requires an Integer. So VM has to guard for Floats and convert Float (-0) into Integer(0);
2) VMs have special "fast" arrays for all integers but use a more generic (slower) array for an array of mixed types (such as Integers and Floats)
Different browsers have different perf penalties for this, but my tests show a 3-10x slow down on Apple M1:
First, these tweets are not meant to make fun of JS but rather to share the understanding that there is no "magic" in the VM and that VM needs to solve problems where it has "insufficient" information.
2/5
How the VMs solve the "lack of information" problem is fascinating, observable, and in some rare cases, may have consequences for how you write your code. So it is helpful to understand it.
3/5
Colocating client/server code in a single file is the next battleground for better DX between meta frameworks.
Let's zoom into what it is!
🧵🪡🧶
Module extraction is the way it is done today. 1) Well-known top-level function invoked by the server but tree-shaken by the bundler for the client. 2) Some form of manual type safety.
(no special code transformation needed)
Function Extraction requires code transformation, which can extract inlined functions into top-level exports (module extraction)
Advantage:
- A lot more natural DX
- Automatic type safety
- Any number of functions (not just well-known exports)