What the heck is the event loop anyway? | Philip Roberts | JSConf EU

JSConf
9 Oct 201426:52

Summary

TLDRIn this insightful talk, Phillip Roberts from AndYet explores the intricacies of JavaScript's event loop and its role in asynchronous programming. He delves into how the single-threaded nature of JavaScript handles concurrency with the help of web APIs, the event loop, and the callback queue. Through examples and a tool called 'loop,' he illustrates the impact of blocking code on UI responsiveness and the importance of asynchronous callbacks for creating fluid user experiences.

Takeaways

  • 😀 Phillip Roberts, a JavaScript developer from AndYet, discusses the event loop and its importance in understanding JavaScript's asynchronous behavior.
  • 🧠 JavaScript is a single-threaded language with a single call stack, meaning it can only execute one operation at a time.
  • 🔁 The event loop is a mechanism that allows JavaScript to handle asynchronous operations by queuing callbacks and running them once the call stack is clear.
  • 📚 Phillip's journey of learning about JavaScript's internals began with a lack of understanding of terms like V8 and single-threaded, leading to 18 months of research.
  • 🤔 The speaker emphasizes the difference between web APIs provided by the browser and the JavaScript Runtime (like V8), highlighting that features like `setTimeout` are not part of the V8 source code.
  • 🛑 Blocking code can cause the browser to become unresponsive, as it cannot perform other tasks while the call stack is full, affecting the user interface negatively.
  • 🔄 Asynchronous callbacks are a solution to avoid blocking; they allow the browser to perform other tasks while waiting for the callback to execute after a certain condition is met.
  • 🕰️ `setTimeout` is used to defer the execution of a function until after a specified delay, but it's important to note that it doesn't guarantee exact timing due to how the event loop and callback queue work.
  • 🔄 The event loop checks the call stack and task queue, running the first task in the queue if the stack is empty, which is crucial for the execution of asynchronous callbacks.
  • 🌐 Web APIs like AJAX, DOM events, and timeouts are part of the browser's environment and work in conjunction with the JavaScript Runtime to provide non-blocking operations.
  • 🎛️ The speaker introduces a tool called 'loop' to visualize the JavaScript Runtime, demonstrating how asynchronous operations and event handling work in real-time.

Q & A

  • What is the main topic of Phillip Roberts' talk?

    -The main topic of Phillip Roberts' talk is the event loop in JavaScript and how it relates to asynchronous behavior in the language.

  • What does Phillip Roberts do for a living?

    -Phillip Roberts works for AndYet, a development shop in the US that specializes in real-time applications.

  • Why did Phillip Roberts start researching JavaScript's inner workings?

    -Phillip Roberts started researching JavaScript's inner workings because, as a professional JavaScript developer, he realized he didn't fully understand how JavaScript actually works, particularly concepts like V8, single-threading, and callbacks.

  • What is Phillip Roberts' main research focus?

    -Phillip Roberts' main research focus is understanding the complexities and nuances of JavaScript to improve his development skills.

Outlines

00:00

👋 Introduction to the Event Loop in JavaScript

Phillip Roberts, a JavaScript developer from AndYet, introduces the concept of the event loop in JavaScript. He starts by acknowledging his own curiosity about how JavaScript operates at a deeper level, prompting an 18-month exploration. He explains that JavaScript is single-threaded and has a call stack but lacks certain asynchronous features like setTimeout within the V8 engine. He aims to clarify the event loop's role in JavaScript's asynchronous behavior and its integration with web APIs, which handle tasks like DOM manipulation, AJAX, and timeouts outside the V8's scope.

05:04

🔁 Understanding the Call Stack and Blocking Behavior

The speaker delves into the JavaScript call stack, explaining how it records the program's execution path and how functions are pushed and popped from it. He illustrates this with a simple code example and discusses the implications of blocking behavior, where slow operations like network requests or heavy computations can halt the execution of subsequent code. The talk also touches on browser-specific behaviors like stack traces for errors and the concept of 'blowing the stack' due to excessive recursion.

10:07

🔄 The Role of Asynchronous Callbacks and Event Loop

Phillip explains the necessity of asynchronous callbacks in JavaScript to prevent blocking the single-threaded call stack. He demonstrates how setTimeout works as an asynchronous callback, showing that it queues a function to be executed after a delay without blocking the stack. The event loop is introduced as the mechanism that monitors the call stack and task queue, executing queued callbacks when the stack is clear, thus enabling concurrency in JavaScript.

15:11

🕰️ setTimeout Clarifications and Asynchronous Patterns

The speaker clarifies common misconceptions about setTimeout, emphasizing that it does not guarantee immediate execution but rather a minimum time before execution. He uses examples to show how callbacks are queued and executed, including the use of setTimeout with a delay of zero, which defers code execution to the end of the current call stack. The talk also explores the difference between synchronous and asynchronous callbacks, illustrating the impact on the call stack and task queue.

20:16

🎛️ Visualizing JavaScript Runtime with the 'loop' Tool

Phillip introduces a tool he developed called 'loop' to visualize the JavaScript Runtime during execution. The tool demonstrates how asynchronous APIs like setTimeout and addEventListener work, showing how callbacks are queued and processed. He uses the tool to run through various examples, including handling multiple setTimeout calls and illustrating the difference between synchronous and asynchronous forEach operations on an array.

25:17

🖌️ The Impact of JavaScript Execution on Browser Rendering

The final paragraph discusses the interplay between JavaScript execution and browser rendering. Phillip explains that the browser aims to repaint the screen every 16.6 milliseconds but is constrained by JavaScript execution on the call stack. He uses the 'loop' tool to simulate rendering and shows how slow synchronous code can block rendering, affecting UI responsiveness. The talk concludes with an example of scroll event handlers that could flood the queue with callbacks, emphasizing the importance of not blocking the event loop for a smooth user experience.

Mindmap

Keywords

💡Event Loop

The event loop is a programming construct that allows single-threaded environments like JavaScript to handle asynchronous operations efficiently. It is central to the video's theme as it explains how JavaScript manages to perform non-blocking operations. In the script, Phillip Roberts uses the event loop to illustrate how callbacks are processed after they are added to the task queue once the call stack is clear.

💡JavaScript Runtime

The JavaScript Runtime, exemplified by V8 in the video, is the environment in which JavaScript code is executed. It includes components like the call stack and heap memory. The script emphasizes that web APIs like `setTimeout` are not part of the V8 source code but are provided by the browser, highlighting the separation between the runtime and the APIs that enable asynchronous behavior.

💡Call Stack

The call stack is a data structure that keeps track of the function calls made in JavaScript. It is crucial for understanding the video's content as it is the primary mechanism for executing synchronous code. The script uses the call stack to demonstrate how functions are executed one at a time and how errors can lead to a stack trace, showcasing the stack's role in debugging and execution flow.

💡Heap

The heap is a region of the runtime where memory allocation for objects occurs. While not the central focus, the heap is mentioned in the script as part of the JavaScript Runtime's structure. It is important for understanding how memory is managed during the execution of JavaScript code.

💡Web APIs

Web APIs are the interfaces provided by the browser that allow JavaScript to interact with the underlying system, such as making network requests or manipulating the Document Object Model (DOM). The script explains that these APIs, which include `setTimeout` and DOM manipulation functions, are separate from the JavaScript Runtime and are key to handling asynchronous operations.

💡Asynchronous Callbacks

Asynchronous callbacks are functions that are called after a certain operation completes or at a later point in time. They are a fundamental concept in the video, which shows how they are used to handle operations that would otherwise block the execution of code. The script provides examples of using `setTimeout` to defer the execution of code, demonstrating the use of asynchronous callbacks in JavaScript.

💡Single-threaded

Single-threaded refers to the ability of a system to execute only one piece of code at a time. The script explains that JavaScript is single-threaded, which means it can only perform one operation at a time on its call stack. This concept is essential for understanding the necessity of asynchronous programming in JavaScript to prevent blocking the user interface.

💡Blocking

Blocking, in the context of the video, refers to operations that slow down or halt the execution of subsequent code due to their time-consuming nature. The script discusses how synchronous operations can block the call stack, preventing the browser from performing other tasks like rendering updates to the user interface.

💡Concurrency

Concurrency is the ability of a system to deal with multiple tasks at the same time, even though it may only have one processor. The script explains that while JavaScript's runtime is single-threaded, the browser itself provides mechanisms for concurrency through web APIs, allowing for asynchronous operations to occur without blocking the main thread.

💡Task Queue

The task queue, also known as the callback queue, is where callbacks for asynchronous operations are stored until they can be executed. The script describes how the event loop checks this queue and, if the call stack is clear, pushes the first callback onto the stack for execution, illustrating the queue's role in managing the order of asynchronous tasks.

💡Rendering

Rendering in the script refers to the process of the browser drawing the user interface based on the current state of the DOM. It is mentioned in the context of how JavaScript execution can affect the browser's ability to perform rendering updates. The script uses a simulated render queue to demonstrate the importance of not blocking the JavaScript thread to maintain a fluid user interface.

Highlights

Phillip Roberts discusses the JavaScript event loop and its components, such as the call stack, event loop, and callback queue.

Roberts shares his journey of understanding how JavaScript works, including terms like V8, single-threaded, and callbacks.

The talk focuses on making sense of JavaScript's single-threaded nature and the role of the event loop in handling asynchronous callbacks.

Roberts explains the JavaScript Runtime, emphasizing that functions like setTimeout and HTTP requests are not part of V8 but are provided by the browser as web APIs.

A key takeaway is understanding that the JavaScript Runtime can only do one thing at a time due to its single-threaded nature.

He uses a simple example to illustrate how the call stack operates, pushing and popping function calls.

Roberts demonstrates how blocking behavior, such as synchronous AJAX requests, can freeze the browser, preventing it from rendering or running other code.

Asynchronous callbacks are presented as a solution to blocking behavior, allowing code to run without freezing the browser.

The concept of setTimeout with zero delay is explained as a way to defer code execution until the call stack is clear.

Roberts introduces the event loop's role in managing the call stack and task queue, ensuring non-blocking execution of asynchronous code.

He visualizes the event loop and explains how web APIs push callbacks to the task queue, which the event loop then processes.

A live coding demonstration is used to show the difference between synchronous and asynchronous code execution.

Roberts highlights the importance of avoiding slow code on the call stack to maintain a smooth user interface.

The talk addresses common issues like debouncing scroll handlers to prevent flooding the task queue with too many callbacks.

Roberts concludes by emphasizing the significance of understanding the event loop for efficient JavaScript programming and invites further discussion on his visualization tool.

Transcripts

play00:01

>> (Phillip Roberts) hello, come in and sit down.

play00:04

So for the last session before the afternoon break, we have Phillip Roberts who works at

play00:10

Andea and is here from London ‑‑ Scotland.

play00:12

Edinbrough.

play00:13

 ‑‑ wow, ten second memory, he's going to talk about the vent loop.

play00:17

If everyone could give Phillip a big brownedder round of applause.

play00:18

>> Phillip Roberts: Okay hello everyone, thanks for coming to the side track, it's awesome

play00:20

to see it packed out in here.

play00:22

Can everyone give me a stretch.

play00:24

I needed to stretch, so I look less weird.

play00:31

I want to talk about the event loop and what the heck is the event loop, as in the event

play00:37

loop inside JavaScript.

play00:39

So first up, as he said I work for AndYet which is an awesome little Dev shop in the

play00:46

US, look us up if you need help with real‑time stuff.

play00:50

That's what we're good at.

play00:52

So, about 18 months ago--I'm a paid professional JavaScript developer--I thought to myself

play01:00

how does, like JavaScript actually work?

play01:03

And I wasn't entirely sure.

play01:05

I'd heard V8 as a term, chrome's Runtime didn't really know what that meant, what that did.

play01:12

I'd heard things like single threaded, you know obviously I'm using callbacks.

play01:16

How do callbacks work?

play01:17

I started a journey of like reading and research and experimenting in the browser which basically

play01:25

started like this.

play01:26

 ‑‑ I was kind of like JavaScript what are you.

play01:30

I'm a single threaded single concurrent language ‑‑ right.

play01:35

yeah, cool, I have a call stack, an event loop, a callback queue, and some other APIs

play01:41

and stuff.

play01:42

 ‑‑ rite.

play01:43

I did not do a computer science degree.

play01:45

I mean, these words, they're words, so I heard about V8 and the various Runtimes and different

play01:51

browsers so I looked to V8 do you have a call stack, an event loop, a callback queue, and

play01:55

some other APIs and stuff, I have a call stack and a heap, I don't know what those other

play02:00

things are, okay, interesting so basically 18 months passed.

play02:09

And I think I get this.

play02:12

(Laughing) and so, this is what I want to share with you today.

play02:15

Hopefully this will be useful if you're relatively new to JavaScript, help you understand why

play02:21

JavaScript is so weird when you compare it to other languages you might used why callbacks

play02:26

are a thing, cause us hell but are required.

play02:29

And if you're an experienced JavaScript developer hopefully give you some fresh insights how

play02:35

the Runtime you're using works so you can think about it a little better.

play02:40

So if we look at the JavaScript Runtime itself like V8 which is the Runtime inside Chrome.

play02:51

This is a simplified view of what JavaScript Runtime is.

play02:55

The heap, where memory allocation happens, and then there's the call stack, which is

play03:01

where your stack frames are and all that kind of stuff, but, if you, like, clone the V8

play03:09

code base and grep for things like setTimeout or DOM or HTTP request, they're not in there,

play03:17

they don't exist in V8, which was a surprise to me.

play03:21

It's first thing you use when you start thinking about async stuff and it's not in the V8 source.

play03:27

Hmm ... interesting.

play03:29

So, over this 18 months of discovery I come to realize this is really, this is really

play03:35

the bigger picture, this is what I'm hoping to get you on board with today and understand

play03:40

what these pieces are, we have the V8 Runtime but then we have these things called web APIs

play03:45

which are extra things that the browser provides.

play03:47

DOM, AJAX, time out, things like that, we have this mythical event loop and the callback

play03:54

queue.

play03:55

I'm sure you've heard some of these terms before, but maybe you don't quite understand

play03:59

how these pieces pull together.

play04:01

So, I'm going to start from the beginning, some of this will be new, to words might be

play04:06

new to people, other people will get this.

play04:08

We're going to quickly move on from here, bear with me if this is obvious, I think for

play04:13

a lot of people it's not.

play04:16

So, JavaScript is a single threaded programming language, single threaded Runtime, it has

play04:21

a single call stack.

play04:23

And it can do one thing at a time, that's what a single thread means, the program can

play04:28

run one piece of code at a time.

play04:30

So, let's try and visualize that just to get our heads around what that mean, so if I have

play04:35

some code like this on your left, we've got a few functions, a function multiplier which

play04:40

multiplies two numbers, square which calls multiply with the same number twice, a function

play04:46

which prints the square of a number of calling square and then calling console.log and then

play04:51

at the bottom of our file we actually run print square, this code all good?

play04:55

Make sense?

play04:56

Cool.

play04:57

So, if we run this, well, I should back up a step, so the call stack is basically ‑‑

play05:04

it's a data structure which records basically where in the program we are, if we step into

play05:08

a function, we put something on to the stack, if we return from a function, we pop off the

play05:12

top of the stack that's all the stack can do, ‑‑ so if you run this file, there's

play05:18

kind of a main function, right, like the file itself, so, we push that on to the stack.

play05:23

Then we have some function definitions, they're just like defining the state of the world,

play05:28

and finally we got to print square, right, so print square is a function call, so we

play05:32

push that on to the stack, and immediately inside print square, push on to the stack,

play05:37

which calls multiply, now we have a return statement, we multiply A and B and we return,

play05:43

when we return we pop something off the stack, so, pop, multiplier of the stack, returning

play05:48

to square, return to print square, console.log, there's no return, it's implicit, because

play05:57

we got to the end of the function, and we're done so that's like a visualization of the

play06:01

call stalk, does that make sense?

play06:05

(Yes, Phil) even if you haven't thought about the call stack before, you've come across

play06:11

it when you've been doing browser‑side development, so if we have code like this, a function baz

play06:18

which calls bar, which calls Foo, which throws an error if we run it in Chrome we see this.

play06:26

And it prints the stack trace, right, the state of the stack when that error happened,

play06:32

so, uncaught error oops Foo, bar, Baz, anonymous function, which is our main.

play06:40

Equally, if you've heard the term like blowing the stack, this is an example of that.

play06:46

Have a function foo which calls Foo , so what's going to happen ? We have a function main

play06:52

which calls foo which calls foo, which calls foo, which calls foo, and ultimately chrome

play07:00

says, you probably didn't mean to call foo 16,000 times recursively, I'll just kill things

play07:07

for you and you can figure out where your bug lies, right.

play07:10

So although I may be representing a new side of the call stack you have some sense of it

play07:16

in your development practice already.

play07:18

So, the big question then comes is like what happens when things are slow?

play07:24

So, we talk about blocking and blocking behavior and blocking, there's no strict definition

play07:31

of what is and didn't blocking, really it's just code that's slow.

play07:35

So console.log isn't slow, doing a while loop from one to ten billion is slow, network requests

play07:41

are slow.

play07:42

Image requests are slow.

play07:46

Things which are slow and on that stack are what are blocking means.

play07:52

So heres a little example, so let's say we have, this is like a fake bit of code, getSynchronous,

play07:59

right, like jQuery is like, AJAX request.

play08:03

What would happen if those were synchronous requests, forget what we know about async

play08:07

callbacks they're synchronous.

play08:10

If we go through it like we have, we call getSync and then we wait, because then we're

play08:16

doing network request, network is relative to computers, are slow, hopefully that network

play08:21

requests completes, we can move on, wait, move on.

play08:27

Wait, and, I mean, this network request might never finish, so ... yeah, I guess I'll go

play08:37

home.

play08:38

Finally those three, you know blocking behaviors complete and we can clear the stack, right.

play08:43

So in a programming language is single threaded you're not using threads like say Ruby, that's

play08:49

what happens, right, we make a network request, we have to just wait till it's done, because

play08:54

we have no way of handling that.

play08:56

Why is this actually a problem?

play09:00

The problem is because we're running code in browsers.

play09:04

So, let's you ‑‑ here we go, okay.

play09:10

So this is just, this is Chrome, this is the code I just ran.

play09:15

Browsers don't give us ‑‑ well they do give us synchronous AJAX request, I'm faking

play09:20

this out with a big while loop, because it's synchronous, I basically while loop for five

play09:26

seconds before continuing, so if I open up the console here.

play09:33

We can see what happens, so with request foo.com, why this is happening, I can't do anything,

play09:40

right, even the run button hasn't finished rerendering the fact that I clicked it.

play09:44

The browser is blocked, it's stuck, it can't do anything until those requests complete.

play09:51

And then all hell breaks loose because I did some stuff,it figured that out I'd done it,

play09:55

it couldn't actually render it.

play09:58

Couldn't do anything.

play10:00

That's because if that call stack has things on it, and here it's got these yeah, it's

play10:07

still going.

play10:08

We've got the synchronous request, the browser can't do anything else.

play10:12

It can't render, it can't run any other code, it's stuck.

play10:16

Not ideal, right if we want people to have nice fluid UIs, we can't block the stack.

play10:22

So, how do we handle this?

play10:24

Well the simplest solution we're provided with is asynchronous callbacks, there's almost

play10:29

no blocking functions in the browser, equally in node, they're all made asynchronous, which

play10:36

basically means we run some code, give it a callback, and run that later, if you've

play10:42

seen JavaScript you've seen asynchronous callbacks, what does this actually look like.

play10:47

Simple example to remind people where we're at.

play10:51

Code like this, console.log hi.

play10:53

Write, we run the setTimeout, but that queue's the console log for future so we skip on to

play11:00

JSConf and then five seconds later we log "there" right, make sense?

play11:06

Happy.

play11:07

Basically that's setTimeout is doing something.

play11:09

So, asynchronous callbacks with regards to the stacks we saw before ... how does this

play11:15

work?

play11:16

Let's run the code.

play11:18

Console.log hi.

play11:21

setTimeout.

play11:22

We know it doesn't run immediately, we know it's going to run in five seconds time, we

play11:28

can't push it on to the stack, somehow it just disappears, we don't have like a way

play11:34

of describing this yet, but we'll come to it.

play11:37

We log JSConfEU, clear, five seconds later somehow magically "there" appears on the stack.

play11:44

How does that happen?

play11:48

And that's ‑‑ this is basically where the event loop comes in on concurrency.

play11:53

Right, so I've been kind of partially lying do you and telling you that JavaScript can

play11:58

only do one thing at one time.

play12:00

That's true the JavaScript Runtime can only do one thing at one time.

play12:03

It can't make an AJAX request while you're doing other code.

play12:06

It can't do a setTimeout while you're doing another code.

play12:09

The reason we can do things concurrently is that the browser is more than just the Runtime.

play12:15

So, remember this diagram, the JavaScript Runtime can do one thing at a time, but the

play12:19

browser gives us these other things, gives us these we shall APIs, these are effectively

play12:23

threads, you can just make calls to, and those pieces of the browser are aware of this concurrency

play12:31

kicks in.

play12:33

If you're back end person this diagram looks basically identical for node, instead of web

play12:38

APIs we have C++ APIs and the threading is being hidden from you by C++.

play12:48

Now we have this picture let's see how this code runs in a more full picture of what a

play12:53

browser looks like.

play12:54

So, same as before, run code, console log hi, logs hi to the console, simple.

play13:01

now we can see what happens when we call setTimeout.

play13:05

We are ‑‑ we pass this callback function and a delay to the setTimeout call.

play13:11

Now setTimeout is an API provided to us by the browser, it doesn't live in the V8 source,

play13:17

it's extra stuff we get in that we're running the JavaScript run

play13:22

time in.

play13:25

The browser kicks off a timer for you.

play13:27

And now it's going to handle the count down for you, right, so that means our setTimeout

play13:33

call, itself is now complete, so we can pop off the stack.

play13:37

“JSConfEU”, clear, so, now we've got this timer in the web API, which five seconds later

play13:45

is going to complete.

play13:46

Now the web API can't just start modifying your code, it can't chuck stuff onto the stack

play13:52

when it's ready if it did it would appear randomly in the middle of your code so this

play13:58

is where the task queue or callback queue kicks in.

play14:00

Any of the web APIs pushes the callback on to the task queue when it's done.

play14:07

Finally we get to the event loop, title of the talk, what the heck is the event loop

play14:12

is like the simplest little piece in this whole equation, and it has one very simple

play14:18

job.

play14:19

The event loops job is to look at the stack and look at the task queue.

play14:22

If the stack is empty it takes the first thing on the queue and pushes it on to the stack

play14:26

which effectively run it.

play14:29

So here we can see that now the stack is clear, there's a callback on the task queue, the

play14:34

event loop runs, it says, oh, I get to do something, pushes the callback on to the stack.

play14:39

Remember it's the stack is like JavaScript land, back inside V8, the callback appears

play14:45

on the stack, run, console.log “there”, and we're done.

play14:49

Does that make sense?

play14:52

Everyone where me?

play14:53

Awesome!

play14:54

Okay.

play14:55

So, now we can see how this works with probably one of the first encounters you would have

play15:00

had with Async stuff which for some weird reason someone says says you have to call

play15:04

setTimeout zero, ‑‑ okay, you want me to run the function in zero time?

play15:11

Why would I wrap it in a setTimeout?

play15:12

Like the first time you run across this, if you're like me,i see it doing something, but

play15:17

I don't know why.

play15:20

The reason is, generally, if you're trying to defer something until the stack is clear.

play15:25

So we know looking at this, if you've written JavaScript, that we're going to see the same

play15:29

result, we're going to see “hi” “JSConf”, and “there” is going to appear at the

play15:33

end.

play15:35

We can see how that happens.

play15:38

The setTimeout zero, now it's going to complete immediately and push it on to the queue, remember

play15:44

what I said about the event loop, it has to wait till the stack is clear before it can

play15:47

push the callback on to the stack, so your stack is going to continue to run, console.log

play15:53

“hi”, “JSConfEU” and clear, now the event loop can kick in and call your callback.

play16:00

That's like an example of setTimeout zero, is deferring that execution of code, for whatever

play16:07

reason to the end of the stack.

play16:11

Or until stack is clear.

play16:13

Okay.

play16:14

So, all these web APIs work the same way, if we have AJAX request, we make an AJAX request

play16:21

to the URL with a callback, works the same way, oops sorry, console log, “hi”, make

play16:28

an AJAX request, the code for running that AJAX request does not live in JavaScript Runtime

play16:32

but in the browser as a web API, so we spin it up with a callback in the URL, your code

play16:40

can continue to run.

play16:42

Until that XHR request completes, or it may never complete, it's okay, the stack can continue

play16:47

to run, assuming it completes, gets pushed to the queue,picked up by the event loop and

play16:52

it's run.

play16:55

That's all that happens when an Async call happens.

play16:58

Let's do a crazy complicated example, I hope this going to work, if you haven't realized

play17:05

all this is in keynote there's like I don't know 500 animation steps in this whole deck.

play17:12

(code blows up, flames animation) (Applause) J Whew ... no ... so ... interesting, we're

play17:35

given a link.

play17:38

Hmm ... is this big enough, can people see?

play17:42

Okay, so basically I wrote this talk for Scotland JS, after the talk I broke half of the slides

play17:52

and could not be bothered to redo all the slides because it was a total pain in the

play17:56

ass in keynote to do it so I took much easier route (Laughing) of writing a tool that can

play18:05

visualize the JavaScript Runtime at Runtime, and it's called loop.

play18:11

So, let's just run this example and, which was kind of the example that we had on the

play18:16

previous slide, I haven't shimmed XHR yet, it's doable I just haven't done it.

play18:23

As you can see the code, we're going to log something, this is a shim around addEventListener,

play18:30

setTimeout and we're going to do a console.log. ‑‑

play18:33

I'm going to run it and see what happens so ... add a DOM API, add a timeout, code is

play18:40

going to continue to run, pushes the callback into the queue which runs, and we're done.

play18:49

If I click on here then it's going to ... trigger the web API, queue the callback for the click

play18:54

and run it.

play18:56

if I cluck a hundred times we can see what happens.

play18:59

I clicked, the click doesn't get processed immediately, itself gets pushed to the queue,

play19:05

as the queue gets processed, eventually my click is going to get dealt with, right.

play19:12

So I have a few more examples I'm going to run through here.

play19:14

Here we go, okay, so, I'm just going to run through a few examples just to kind of talk

play19:29

about a few things that you might have run in to and not thought about with Async APIs,

play19:33

In this example we call setTimeout four times with the one second delay, and console.log

play19:40

“hi”.

play19:43

By the time the callbacks get queued... that fourth callback we asked for a one second

play19:52

delay, and it's still waiting, the callback hasn't run, right .

play19:56

this illustrates the ‑‑ like what time out is actually doing, it's not a guaranteed

play20:02

time to execution, it's a minimum time to execution, just like setTimeout zero doesn't

play20:06

run the code immediately it runs the code next‑ish, sometime, right?

play20:16

So ... in this example I want to talk about callbacks, so, depending on who, speak to

play20:24

and how they phrase things, callbacks can be one of two things, callbacks can be any

play20:29

function that another function calls or callbacks can be more explicitly an asynchronous callback

play20:34

as in one that will get pushed back on the callback queue in the future.

play20:39

This bit of code illustrates the difference, right.

play20:42

The forEach method on an array, it doesn't run, it takes a function, which you could

play20:48

call a callback, but it's not running it asynchronously, it's running it within the current stack.

play20:55

We could define an asynchronous forEach so it can take an array, a callback and for each

play21:02

item in the array it's going to do a setTimeout zero with that callback, I guess this should

play21:08

pass in the value, but any way, so, I'm going to run it and we can see what the difference

play21:13

is, so for the first block of code that runs, it's going to sit and block the stack, right?

play21:20

Until it's complete, whereas in the Async version, okay, it's slowed down, but we're

play21:26

basically going to queue a bunch of callbacks and they're going to clear and then we can

play21:31

actually run through and do a console.log.

play21:34

In this example the console.log is fast, so the benefit of doing it asynchronously is

play21:39

not obviously but let's say you're doing some slow processing on each element in the array.

play21:48

I think I have that shown somewhere no, no, I don't.

play21:55

Okay.

play21:56

So let's say ‑‑ Ooops.

play22:00

So I have a delay function which is just slow, it's just a slow thing.

play22:06

So ... let's say processing Async and here processing Sync.

play22:15

Okay, now, I'm going to turn on a thing I've literally hacked together this morning, which

play22:23

is to simulate the repaint or the render in the browser, something I haven't touched on

play22:27

is how all of this interacts with rendering ‑‑ I've kind of touched on it but not really

play22:34

explained it.

play22:36

So, basically the browser is kind of constrained by what you're doing javaScript, the browser

play22:42

would like to repaint the screen every 16.6 milliseconds, 60 frame a second is ideal,

play22:48

that's the fastest it will do repaints if it can.

play22:52

But it's constrained by what you're doing in JavaScript for various reasons, so it can't

play22:57

actually do a render if there is code on the stack, right.

play23:02

Like the render kind of call is almost like a callback in itself.

play23:05

It has to wait till the stack is clear.

play23:07

The difference is that the render is given a higher priority than your callback, every

play23:13

16 milliseconds it's going to queue a rend, wait till the stack is clear before it can

play23:21

actually do that render.

play23:23

So this is ‑‑ this render queue is just simulating a render, every second it's can

play23:27

I do a render?

play23:28

Yes, can I do a render?

play23:29

Yes.

play23:30

Where, because our code isn't doing anything now.

play23:33

If I run the code, you can see while we're doing this slow synchronous loop through the

play23:39

array, our render is blocked, right, if our render is blocked you can't select text on

play23:44

the screen, you can't click things and see the response, right, like the example I showed

play23:50

earlier.

play23:51

In this example, okay, it's blocked while we queue up the async time out, that relatively

play23:57

quick but we're given ‑‑ we're kind of giving the render a chance between each element

play24:04

because we've queued it up asynchronously to jump in there and do the render, does that

play24:12

make sense?

play24:13

>> Yeah >> Yeah, cool.

play24:14

So, that's just kind of ‑‑ this is just like a simulation of how the rendering works,

play24:19

but it just really shows you when people say don't block the event loop, this is exactly

play24:23

what they're talking about.

play24:24

They're saying don't put shitty slow code on the stack because when you do that the

play24:27

browser can't do what it needs to do, create a nice fluid UI.

play24:33

This is why when you're doing things like image processing or Animating too many things

play24:38

gets sluggish if you're not careful about how you queue up that code.

play24:44

So an example of that, we can see with the scroll handlers ‑‑ so scroll handle ‑‑

play24:53

like scroll events in the DOM trigger a lot, right, they trigger like ‑‑ I presume

play24:58

they trigger on every frame like every 16 milliseconds, if I have code like this this

play25:04

right.

play25:05

On document.scroll, animate something, or do some work.

play25:11

If I have this code, like as I scroll it's going to queue up like a ton of callbacks

play25:16

right.

play25:18

And then it has to go through and process all of those and each of the processing of

play25:21

those is slow, then, okay, you're not blocking the stack, you're flooding the queue with

play25:27

queued events.

play25:29

So, this is like just helping visualize, I guess, what happens when you actually trigger

play25:35

all these callbacks, there's way you can debounce that to basically say okay, we're going to

play25:42

queue up all those events, but let's do the slow work every few seconds or until the user

play25:48

stops scrolling for some amount of time I think that's basically it.

play25:58

There's a whole other talk in how the hell this works.

play26:03

Because basically in running the code, like this code runs at Runtime, right, and it's

play26:09

slowed down by I run it through a Esprima a JavaScript parser, I insert a big while

play26:17

loop, that takes half a second, it just slow motions the code.

play26:23

Ship it to web worker and do a whole bunch of stuff to visualize what's happening while

play26:28

doing it at run time that makes sense.

play26:31

A whole other talk in that.

play26:33

I'm super excited about it and will talk to anyone about it after because I think it's

play26:38

kind of neat, so with that, thanks very much ( applause)

Rate This

5.0 / 5 (0 votes)

関連タグ
JavaScriptEvent LoopAsynchronousCallbacksWeb APIsConcurrencyPerformanceRuntimeV8 EngineDeveloper InsightsTechnical Talk
英語で要約が必要ですか?