JS perfs tooling that came in clutch
how something that looks like a performace improvement for JS turned out to be such a big design decision
Yesterday while walking down the road, I was discussing with my friend Vedant, whether JS is compiled or interpreted, which led me to burrow down into some rabbit holes. And here we are now, with me condensing down my thoughts and chrome history for you xD.
First things first, what do you think JS is an interpreted language or a compiled one?
feel free to google/gpt.
you will probably find that it’s an interpreted one. All scripting languages are, nothing new right?
hmmmm, alright
Let’s try this, open your dev tools console.
let a= hello(5);
function hello(num){
console.log("hello called");
return num;
}
If js is an interpreted language, you should have gotten an error, since you tried to call a function that was not defined yet, as it is below in the order.
But But But…
the script worked.
HOW? WHY? JS is supposed to be an interpreted language.
was all your life google/gpt wrong telling you its an interpreted language and not a compiled one, like how else can it call a function that is not defined yet?
turns out something else had a role to play
enters the main character of the story the V8 engine (tadaaaa🎊 in BGM).
What is a V8 engine? and what does it do?
V8 is the name of javascript engine, that most probably powers your browser and also powers the most popular js runtime node. V8 is written in C++, and it's continuously improved. It is portable and runs on Mac, Windows, Linux and several other systems.
JavaScript is internally compiled by V8 with just-in-time (JIT) compilation to speed up the execution.
Like typical of any compiler, compilation can be divided in following steps:
Code Parsing for tokenization
creation of Abstract Syntax Trees(AST),
conversion to byte code,
Conversion to Machine code,
executing the code.
The first 2 steps are what you popularly call the creation phase of JS.
The Later steps are popularly called the execution phase of JS.
the parser in V8 generates nodes from the js code, which are used to create abstract syntax trees.
Now this is where things get really crazy.
The js file gets parsed, the code we write gets tokenized, and that then gets converted to an AST.
This AST tree can now be compiled into
a) Byte code,
b) Machine code, or
c) both
It’s about the trade-offs. It starts with the first compilation and interpretation until the first statement is executed. After that V8 may choose to compile more performance-sensitive ( repetitive or hot code as we call it at times ) while the remaining part gets interpreted.
Byte code gets executed by the interpreter as language interpreter directly executes it, while the code that did not get converted to Byte code since it was perf sensitive, get converted down to machine code, which is directly executed in the machine.
Fun Fact: At the start of the discussion we took a script as an example and saw how we were able to call the function before it was defined, that happened due to functions getting declared at the top of the tree(AST), so js can manage memory accordingly and this function also got assigned its value there, making sure that we were able to call the function in the block before defining its value. This is called Function hoisting.
Q: Why we don’t do the same for var also, since they are also readable before the assignment, but return undefined???
A: These are some special previleges given to a function, its the feature of the language. Also it has its own advantages with regards to the perf of the language. This would have been more of a design decision taken while these features/paradigms were being implemented for the language by it’s creators.
Though now this has left my mind with some new rabbit holes to explore in regards to memory management in JS, I guess we have a calling for another cool blog 😆
Sources:
https://nodejs.org/en/learn/getting-started/the-v8-javascript-engine
https://v8.dev/blog/background-compilation
https://v8.dev/blog/improved-code-caching
https://v8.dev/blog/hash-code
Biggest Shoutout to —> https://stackoverflow.com/a/69155309/17824749