{"id":68047,"date":"2016-09-08T13:02:22","date_gmt":"2016-09-08T13:02:22","guid":{"rendered":"https:\/\/www.simple-talk.com\/?p=68047"},"modified":"2022-05-02T20:33:45","modified_gmt":"2022-05-02T20:33:45","slug":"javascript-single-threaded","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/development\/javascript\/javascript-single-threaded\/","title":{"rendered":"Is JavaScript Single-Threaded?"},"content":{"rendered":"<p><strong>TL; DR<\/strong> Your JavaScript code is single-threaded in the same context, but all other stuff which is done by browser (AJAX request, rendering, event triggers etc.) is not.<\/p>\n<p>The execution of any JavaScript program can be divided into two separate parts:<\/p>\n<ul>\n<li>The Initial execution of the code that takes place during page load<\/li>\n<li>The subsequent event-handling<\/li>\n<\/ul>\n<h2>Initial code execution<\/h2>\n<p>We have, for example, a web page with some inline JavaScript code and a few references to JavaScript libraries. How JS code executed on this page? The browser loads the web page and \u2018sees\u2019 a reference to a JavaScript file. When this file is loaded, we could imagine that this JS code is wrapped within an anonymous function. This imaginary function has a global scope as its own function scope and is self-executing. We could imagine it as the following piece of code:<\/p>\n<pre class=\"theme:vs2012 lang:js decode:true \">(function () {\r\n    \/\/ JS file content goes here\r\n})();<\/pre>\n<p><span style=\"line-height: 1.5;\">The next example shows us that JavaScript code is executed as soon as possible after the inline element or file reference is found, and so it doesn\u2019t wait for the creation of the DOM tree to be completed (<\/span><a style=\"line-height: 1.5;\" href=\"https:\/\/jsfiddle.net\/t0k4syxt\/\">JSFiddle link<\/a><span style=\"line-height: 1.5;\">):<\/span>Inline JavaScript code is executed in the same manner, but without the file loading phase. It is important to know that, during this code execution both the creation of the DOM and the rendering of the page is paused. As a result, the user sees a blank page and needs to wait.<\/p>\n<pre class=\"theme:vs2012 lang:js decode:true\">&lt;script&gt;\r\n\u00a0\u00a0\u00a0 var divElement = document.getElementById('someId');\r\n\u00a0\u00a0\u00a0 divElement.innerText = 'Hello, world!'\r\n&lt;\/script&gt;\r\n&lt;div id=\"someId\"&gt;&lt;\/div&gt;<\/pre>\n<p><span style=\"line-height: 1.5;\">Another way to handle JS file loading is to use \u201c<\/span><strong style=\"line-height: 1.5;\">async<\/strong><span style=\"line-height: 1.5;\">\u201d and \u201c<\/span><strong style=\"line-height: 1.5;\">defer<\/strong><span style=\"line-height: 1.5;\">\u201d attributes for the script element. If you don\u2019t know about these attributes or want to know a little bit more about how to load external scripts, please read this great <\/span><a style=\"line-height: 1.5;\" href=\"http:\/\/www.html5rocks.com\/en\/tutorials\/speed\/script-loading\/\">article<\/a><span style=\"line-height: 1.5;\">.<\/span>As you can see, we are trying to access a division element (DIV) that is placed after the script block. In this example we will get an exception because the <strong>divElement <\/strong>variable is null. To avoid JavaScript code trying to access unreachable DOM elements, you will definitely need to place your code at the end of the page or at least execute it after page is loaded.<\/p>\n<h2>Event loop<\/h2>\n<p>Initial code execution ends once the page is loaded and the initial JavaScript code has run, all event handlers are attached, all AJAX requests are sent and our observables are observing. Why then shouldn\u2019t we just handle all the events we are subscribed to in old-fashioned parallel way? The reason is that we don\u2019t want to change the DOM in parallel: this is because the DOM tree is not thread-safe and it would be a mess if we tried to do it. Because of this limitation, all our JavaScript code should be executed in single thread, while at the same time ensuring that it handles all the events and doesn\u2019t lose any callback. For these reasons we come to the Event loop.<\/p>\n<p>The event loop can be imagined as the following process flow:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone  wp-image-68051\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2016\/09\/ProcessFlow.png\" alt=\"ProcessFlow\" width=\"718\" height=\"333\" \/><\/p>\n<p>As described in the picture, the main parts of JavaScript Event loop are:<\/p>\n<ul>\n<li>The<strong> Call stack, <\/strong>which is a usual call stack that contains all called functions.<\/li>\n<li>The<strong> Event handlers queue<\/strong>, a queue of event handlers that are waiting to be executed.<\/li>\n<li>The<strong> Event loop,<\/strong> which is a process that checks whether events handlers queue is not empty and if it is \u2013 calls top event handler and removes it from queue.<\/li>\n<li>The<strong> JavaScript Web APIs<\/strong>: those APIs that are provided by the browser that are responsible for filling the Event handlers queue, providing many features such as the ability to make an AJAX request and e.g. the implementation of Mozilla has a great documentation about Web APIs and it could be found by the <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\">link<\/a>.<\/li>\n<\/ul>\n<p>Each window or <strong>WebWorker<\/strong> has its own event loop. We could imagine that each JS context wraps all code with the following piece of code:<\/p>\n<pre class=\"theme:vs2012 lang:js decode:true \">while (true) {\r\n\u00a0\u00a0\u00a0 if (eventHandlersQueue.isNotEmpty()) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 eventHandlersQueue.processTopEventHandler();\r\n\u00a0\u00a0\u00a0 }\r\n}<\/pre>\n<p><span style=\"line-height: 1.5;\">But why isn\u2019t the page responding during JavaScript execution?<\/span>Of course, the Event loop model as described is a very simplified abstraction of what is actually happening under the hood of a browser. The real implementation could vary from browser to browser, but the main principle is the same. If you want to get more precise information about the Event loop, you could read the corresponding section of WHATWG HTML specification, which you can find by the <a href=\"https:\/\/html.spec.whatwg.org\/multipage\/webappapis.html#event-loop\">link<\/a>.<\/p>\n<p>So far, I\u2019ve described how our JavaScript code is executed during page load, and how the different events are handled by the Event loop. Also we know that we don\u2019t want to change DOM tree in different threads. But what about this piece of code (<a href=\"https:\/\/jsfiddle.net\/odrbuhpv\/\">JSFiddle link<\/a>):<\/p>\n<pre class=\"theme:vs2012 lang:js decode:true\">function calculatePi(numberOfIterations) {\r\n\u00a0\u00a0\u00a0 var pi = 0,\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 n = 1;\r\n\u00a0\u00a0\u00a0 for (var i = 1; i &lt; numberOfIterations; i++) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 pi = pi + (4 \/ n) - (4 \/ (n + 2));\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 n += 4\r\n\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0 return pi;\r\n};\r\n\r\nblockUIButton.onclick = function () {\r\n\u00a0\u00a0\u00a0 calculationResult.innerHTML = calculatePi(1000000000);\r\n}<\/pre>\n<p><span style=\"line-height: 1.5;\">This is all because of reflows. Reflow is a process of recalculation of each element position, style and any other characteristic that is required for proper rendering of the page. It is triggered by adding new DOM element, doing a window resize or making changes in element styles from JavaScript. This reflow process is complex and could significantly slow page render. But it would be even worse if, after each reflow, we had to render the page. In this case, the user would have seen all the steps of page building till the final result but we don\u2019t want such behavior. I have created a small test to show how reflows are causing bad performance, which you can find it by this <\/span><a style=\"line-height: 1.5;\" href=\"https:\/\/jsfiddle.net\/8xayg9z9\/\">link<\/a><span style=\"line-height: 1.5;\">.<\/span>During this code execution, the page is blocked so that the user cannot interact with the page. Some browsers even ask the user to either wait until the page ends its calculation or just kill the process.<\/p>\n<p>One more thing worth mentioning is that page render has higher priority than any handler waiting in the Event handler queue. The Browser tends to render page 60 frames per second or, in other words, one frame approximately each 16 milliseconds. When the call stack is cleared, the browser checks whether it is time to render the page: only then does it check the Event handler queue. Taking into account this new information our, abstractly-coded Event loop is extended with a render-related check:<\/p>\n<pre class=\"theme:vs2012 lang:js decode:true \">while(true){\r\n\u00a0\u00a0\u00a0 if(renderEngine.isItTimeToRender(){\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 renderEngine.render();\r\n\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0 if(eventHandlersQueue.isNotEmpty()){\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 eventHandlersQueue.processTopEventHandler();\r\n\u00a0\u00a0\u00a0 }\r\n}\r\n<\/pre>\n<p>On desktops, it is hard to notice the render part of the event loop, but it could be noticeable on mobile devices where resources are more limited.<\/p>\n<h2>What about asynchronous code in JavaScript?<\/h2>\n<p>All asynchronous code in JavaScript is based on Web APIs that are provided by the browser. These vary on functionality and purpose, but all of them provide the possibility of executing a callback function. We could distinguish two groups of such APIs.<\/p>\n<p>The first big group comprises the APIs that fires a callback after some work is done. It could be handling AJAX request, an <strong>onload<\/strong> handler within the DOM or maybe a web worker response. The callback is fired as when something changes, and the purpose of this callback is to react on this changes. When a callback must be executed, it is added to the Event handlers queue.<\/p>\n<p>The second group includes the <strong>setTimeout(callback, time)<\/strong> and<strong> setInterval(callback, time) <\/strong>functions. For those who never faced these function I should explain:<\/p>\n<ul>\n<li><strong>setTimeout<\/strong> \u2013 runs a callback once after specified amount of time<\/li>\n<li><strong>setInterval<\/strong> \u2013 runs a callback at a specified time interval<\/li>\n<\/ul>\n<p>These functions are not reacting to changes, but just running our code. One of their main purpose is to provide us the means of breaking synchronous execution into asynchronous parts. It is important to remember that these functions don\u2019t guarantee that callback will be executed after the amount of time that you specify. They do guarantee that callback will be added to the Event handlers queue, but, as we know, it could already have handlers waiting for execution. So, \u201ctime\u201d argument should be treated as \u201cnot earlier than, but after the specified time\u201d.<\/p>\n<h2>How to achieve parallelism in JavaScript<\/h2>\n<p>I\u2019ve already mentioned that JavaScript is single-threaded in the same execution context. Because of that we have two options to achieve parallelism in JavaScript.<\/p>\n<p>The first one option is pseudo-parallelism based on <strong>setTimeout<\/strong> function. Its main idea is to unblock user interaction with the interface, but, at the same time, execute logic that is needed to be executed. This approach is based on breaking execution into parts. The following code demonstrates an implementation of this approach (<a href=\"https:\/\/jsfiddle.net\/na7146gr\/\">JSFiddle link<\/a>):<\/p>\n<pre class=\"theme:vs2012 lang:js decode:true\">function appendResult(result) {\r\n\u00a0\u00a0\u00a0 var div = document.createElement('div');\r\n\u00a0\u00a0\u00a0 div.innerText = result;\r\n\u00a0\u00a0\u00a0 results.appendChild(div);\r\n}\r\n\r\nfunction calculatePi(pi, n) {\r\n\u00a0\u00a0\u00a0 for (; ; n += 4) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 pi = pi + (4 \/ n) - (4 \/ (n + 2));\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if ((n - 1) % 20000000 == 0) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 appendResult(pi);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 setTimeout(function () {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 calculatePi(pi, n + 4);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 });\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 return;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0 }\r\n}\r\n\r\nstartCalculation.onclick = function () {\r\n\u00a0\u00a0\u00a0 calculatePi(0, 1);\r\n}<\/pre>\n<p><span style=\"line-height: 1.5;\">The second option is to use WebWorkers. WebWorkers represent the concept of parallel threads in JavaScript, but with some limitations:<\/span>In this example, the calculation is divided into separate blocks so that the user could interact with the interface between the executions of these blocks.<\/p>\n<ul>\n<li>It isn\u2019t possible to access DOM elements inside the web worker instance. Actually you are forbidden to pass any kind of reference to the DOM structure and its related functions.<\/li>\n<li>Communication with the worker is based on messages via the <strong>postMessage<\/strong>() method and \u201c<strong>message<\/strong>\u201d event.<\/li>\n<li>There are no window, document and parent objects inside the worker.<\/li>\n<\/ul>\n<p>All these limitations are added to block any possibility of changing the DOM, which isn\u2019t thread-safe, from inside the workers. The main usage of workers is for heavy background calculations. The following example shows how to use a worker for \u03c0 calculation (<a href=\"https:\/\/jsfiddle.net\/cr5m23es\/\">JSFiddle link<\/a>):<\/p>\n<pre class=\"theme:vs2012 lang:js decode:true\">\/\/ Some magic to run function as WebWorker\r\nvar workerBlob = new Blob([\"(\" + worker.toString() + \")()\"], { type: 'text\/javascript' }),\r\n\u00a0\u00a0\u00a0 workerInstance;\r\n\r\nstartButton.onclick = function () {\r\n\u00a0\u00a0\u00a0 if (workerInstance) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 workerInstance.terminate();\r\n\u00a0\u00a0\u00a0 }\r\n\r\n\u00a0\u00a0\u00a0 output.innerHTML = \"\";\r\n\u00a0\u00a0\u00a0 workerInstance = new Worker(URL.createObjectURL(workerBlob));\r\n\u00a0\u00a0\u00a0 workerInstance.onmessage = function (e) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 output.innerHTML += \"&lt;div&gt;\" + e.data + '&lt;\/div&gt;';\r\n\u00a0\u00a0\u00a0 };\r\n\u00a0\u00a0\u00a0 workerInstance.postMessage(null);\r\n};\r\n\r\nfunction worker() {\r\n\u00a0\u00a0\u00a0 onmessage = function (e) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 var pi = 0,\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 n = 1;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 for (var n = 1; ; n += 4) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 pi = pi + (4 \/ n) - (4 \/ (n + 2));\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0  if ((n - 1) % 200000000 == 0) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 postMessage(pi);\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0  }\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0 };\r\n}<\/pre>\n<p><span style=\"line-height: 1.5;\">If you need to process a big amount of data or to make some heavy calculations and there is no need to support the old versions of browsers, then I would recommend you to use <\/span><strong style=\"line-height: 1.5;\">WebWorkers,<\/strong><span style=\"line-height: 1.5;\"> because of their performance and real implementation of parallelism. But, if you just need to handle a collection of objects and you can sacrifice some time to unlock interface for user interaction, then you can use pseudo-parallelism based on <\/span><strong style=\"line-height: 1.5;\">setTimeout<\/strong><span style=\"line-height: 1.5;\">. I have prepared a small performance comparison that you can play with by the <\/span><a style=\"line-height: 1.5;\" href=\"https:\/\/jsfiddle.net\/6e9s3ge3\/\">link<\/a><span style=\"line-height: 1.5;\">.<\/span>During worker execution, the main Event loop is never blocked; it is only handling message results.<\/p>\n<h2>Conclusion<\/h2>\n<p>Answering the question, JavaScript is single-threaded in the same context, but browser Web APIs are not. Also we have possibility of simulating parallelism by using <strong>setTimeout<\/strong> function or, with some limitations, by the use of the real parallelism provided by WebWorkers.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Developing JavaScript for web pages can be perplexing. You will  get errors that seem to make no sense, You will be given nuggets of advice about how and when you can use JavaScript to manipulate the DOM or make Ajax requests. It is far better to understand the reason for these rules; the single-threaded nature of JavaScript, and how it loads the page and manages the event loop. How can you achieve parallel processing and what is the best way? Igor makes it all clear and obvious.&hellip;<\/p>\n","protected":false},"author":238796,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[146044],"tags":[],"coauthors":[21036],"class_list":["post-68047","post","type-post","status-publish","format-standard","hentry","category-javascript"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/68047","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/238796"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=68047"}],"version-history":[{"count":8,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/68047\/revisions"}],"predecessor-version":[{"id":91035,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/68047\/revisions\/91035"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=68047"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=68047"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=68047"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=68047"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}