DEV Community

Cover image for How Javascript V8 Engine Works?
Kevin Toshihiro Uehara
Kevin Toshihiro Uehara

Posted on

How Javascript V8 Engine Works?

Hi people! It's nice to have you again, or if it's your first time here, be welcome!

Before all, let's ask you something. Do you work with Javascript? whether working with Frontend (React, Angular, Vue, Svelte...) or on Backend (Node, NestJS...).

If your answer probably is "yes". So I will ask another question. Do know how Javascript works?

If your answer is "no" or "hmmmm... I know the basics". This article is for you.

Let's understand how Javascript works on background, based on v8 engine.

First, we need to understand that Javascript is an interpreted language. Therefore, it is interpreted by broswer and compiled in C++, applying the concept of Just in Time (JIT) compiled and non blocking i/o.

JavaScript engines are designed developed the Just In Time (JIT) Compilation model.

Node works using the v8 Javascript engine, created by google, just like Chrome.

So we have differents engines for each browser:

  • Chrome: V8
  • Firefox: SpiderMonkey
  • Safari: JavascriptCore
  • Edge: Chakra (but after some Microsoft update the Edge, now is using the V8)

And we need to remember... Javascript is SINGLE THREAD, but in same time we can use the power of its architecture make asynchronous processes. And this is what i will try to explain in this article.

How Javascript, as single thread language, can deal with asynchronous tasks.

First, let's see some examples:

First Code

console.log('foo');
setTimeout(function timeout() {
  console.log('bar')
}, 1000)
Enter fullscreen mode Exit fullscreen mode

If your answer was:

foo
bar
Enter fullscreen mode Exit fullscreen mode

Congratulations!! you're right!!

But, let's add some complexity...

Second Code

Try to guess the output of this code:

function foo() {
    console.log('foo')
}

function bar() {
    setTimeout(function timeout() {
        console.log('bar')
    }, 2000)
}

console.log('baz')

foo();
bar();
Enter fullscreen mode Exit fullscreen mode

If your answer was:

baz
foo
bar
Enter fullscreen mode Exit fullscreen mode

Congratulations!! you're right!!

Now the last example:

Third code

Try to guess the output of this code:

function foo() {
  console.log("foo");
}

setTimeout(function first() {
  console.log("bar");
}, 7000);

setTimeout(function second() {
  console.log("baz");
}, 4000);

foo();
console.log("xpto");
Enter fullscreen mode Exit fullscreen mode

If your answer was:

foo
xpto
baz
bar
Enter fullscreen mode Exit fullscreen mode

Congratulations!! you're right!!

If you got all the outputs of all the examples right, you should already imagine how javascript works. But if you made a mistake on output, don't worry! I will try to explain in this article how these examples were executed by Javascript.

There are four "entites", that we need to know on Javascript Engines, the main focus will be on V8 Engine:

  • CallStack
  • WebApis or LIBUV (C++ library) - and this is a big spoiler
  • Callback Queue or Event Queue
  • Event Loop

Let's talk one by one:

CallStack

Every command that is read on JS is inserted on a stack, fist in, last out (FILO) (that we called CallStack). So all commands like console.log, function call are pushed on this stack.

WebApis or Libuv

It's where the assyncronous processs happens and stored. To avoid the main thread beeing blocked, process like setTimeout is pushed to the WebApis and popped after the asynchronous process finished. You can find some articles, call the webapis also calling libuv, because this structure is a lib of C++.

Callback Queue or Event Queue

Both names represents the structure where the callbacks of WebApis are stored after finish the execution.

Event Loop

And the main actor of this show... Event Loop. He is responsible to monitor the CallStack and Event Queue to execute the asynchronous process. Think the Event Loop as a "for(;;) or while(true)", that will always be monitoring the execution process and allow to we work with asynchronous tasks on Javascript.
The event loop takes precedence over some structures. The event loop will only run the event queue tasks when the callback stask is empty

We can see the model of this architecture on this example:

V8 architeture Image

Now that you have some idea of this concepts, let's see the execution of each example that I showed above.

I will use the app created by Philip Roberts to demonstrate the execution. See in this video where Philip made a demonstration of Event Loop on JSConf EU.
And you can use the app, accessing:

Demo App: http://latentflip.com/loupe/

So for the first example:

Example 1 gif

  1. The console.log is pushed and executed on callStack
  2. The setTimeout is pushed on WebApis and process the asynchronous process
  3. After the process finished, the callback is pushed on Callback Queue
  4. The Event Loop will realize that there is an event on Call Back Queue and push to Call Stack.

Link for the code execution

So for the second example:

Example 2 gif

  1. The console.log('baz') is pushed and executed on callStack
  2. The function foo() is pushed and executed on callStack
  3. The setTimeout inside of bar() function is pushed on WebApis and process the asynchronous process
  4. After the process finished, the callback is pushed on Callback Queue
  5. The Event Loop will realize that there is an event on Call Back Queue and push to Call Stack.

Link for the code execution

So for the third example:

Example 3 gif

  1. The console.log('foo') is pushed and executed on Call Stack
  2. The first setTimeout with 7 seconds is pushed on Web Apis
  3. The second setTimeout with 4 seconds is pushed on Web Apis
  4. The console.log('Baz') is pushed and executed on Call Stack
  5. The second setTimeout finished first and the callback is pushed on Event Queue to be processed.
  6. Event Loop notice the event on Event Queue and push on Call Stack
  7. Meanwhile the first setTimeout finished also and the callback is pushed on Event Queue.
  8. Notice that the Event Loop will not push the callback of the first function, because the Call Stack is not empty.
  9. After the total execution, the Event Loop push the first callback to the Call Stack to complete.

Link for the code execution

And now it's clearer, how Javascript engine works? How even being single thread can handle asynchronous processes?

The magic happens because of Event Loop and Event Queue. This architecture makes the Javascript non-blocking i/o.

I hope this article has helped clarify how things work behind the scenes.

That's all folks! Thank you so much for read until here!

Thank you Michael Scoot Gif

Top comments (0)