Saturday, November 26, 2016

What requestAnimationFrame is ?

Animation with traditional way

For creating animation with JavaScript, we use setInterval() and setTimeout(). These functions execute the passed function at given time. And with setInterval, there would execute the function after each given time interval. The following example does console the message after every second.

function draw(){
 console.log(“draw something  after every second”);
}
setInterval( draw, 1000 );

Disadvantages of setInterval/setTimeout

So what are the disadvantages of setInterval/setTimeout. It does not care what is going on CPU/ Browser, enough resource is available or not, if there is low or high battery and if a user is in current tab of browser or in another tab. This stuff is not considered by setInterval/setTimeout.

It goes for executing the assigned task at given time of interval, It does not respect CPU resources, browser’s workload etc. These are the reasons, complex setInterval can cause the problem while other application uses the extensive CPU.  As a result, the browser would be unresponsive or crashed.

To overcome the problem

So get rid of all these issues, we can use requestAnimationFrame function. This API is created by people of Mozilla and adopted by other browser vendors, later.

So it’s basically used to create animation with JavaScript, let’s explore how does this work.

function draw() {
 console.log('Your draw code is executed here..');
 requestAnimationFrame(draw);
}
draw();
The draw method displays the message in a console of your browser. We execute this function by invoking draw();. Inside the draw function, after display the message, new draw() is  invoked by requestAnimationFrame(draw). The requestAnimationFrame does not invoke the draw method unless the browser is ready.  

Above script displays the message with 60 frames per second.  Short description about frame rate is mentioned at last of this article.

What if there is a need of less than 60fps

The below code is same like above(requestAnimationFrame) along the disadvantages of setInterval/setTimeout

setInterval(
 function (){
  console.log('Your draw code is executed here..');
 }, (1000/60)
);

If someone wants the frame rate less than 60, what to do? Not to worry, here is the solution. For example, if you want the 16fps by requestAnimationFrame. You could do something like this.

var fps = 16;
function draw() {
 setTimeout(
  function (){
   console.log('Your draw code is executed here..');
   requestAnimationFrame(draw);
  }, (1000/fps)
 );
}


In this code, we use the setTimeout function inside draw method to achieve the 16 frame rate per second.

There are great benefits of using requestAnimation, it asks the browser if there is the possibility of drawing of next frame, It draws only if possible otherwise it ignores.

Suppose you are using setInterval/setTimeout in your page, now you go to another tab in your browser. Chrome/firefox throttles the animation speed by 1 frame per second. However, it does not stop completely.

Traditional vs New way

If you create the same animation by requestAnimationFrame, then the animation task would be stopped and there are no expenses of CPU for this task while you are in another tab. Less CPU means a long battery for your laptop and mobile.

You can see the two different screenshots, first, is using by setInterval and second is using by requestAnimationFrame

animation with a traditional way


animation with requestAnimationFrame way

You can get the complete example over here. To see the difference, switch the tab after rendering these examples in browser

Frame Rate
By default, there is 60fps rate in  requestionAnimationFrame. With javascript, the frame rate is the rate, on which browser draws screen 60 times per second. In normal, the movie would play with 30fps, which means in one second, there are 30 pictures are summed together and presented like the movie.

Saturday, November 19, 2016

Web worker for separate thread in JavaScript

What Web worker is ?


JavaScript is a single-threaded programming language. It would be executed in a single thread only, this is the reason when you use heavy JavaScript code for your application, the UI of application would be blocked because the heavy script uses all CPU with main/single thread.


In a single thread, all the script is executed one by one, If the particular code uses the extensive CPU which means other code can not be executed meanwhile.

As a result, JavaScript application is not able to give the response to user interaction, so It’s pretty bad experience to end user.

Web-worker shines over here, what basically it does is, provide the facility of multi-threading for JavaScript application. So the application can use the heavy code in another thread by using web worker and make free the main thread to respond the user input.


For example, if you run large loop in your JavaScript code, which uses 95% CPU, now suppose user click on a button for any task, then user interface in the browser is not responded, in this case, we can place that heavy code in worker as a separate thread.

So that ”95% CPU consuming code” would be executed in the background with a different thread, and the main thread is available for User Interface.

How to use Web Worker ?

To add the web worker on your page, you could do something like.

 var anyWorker  = new Worker('anyJsFile.js'); 

anyJsFile.js is worker file treated as separate thread, now the worker object is available with anyWorker object,

By using postMessage() method with worker object we can send the data to worker, like

Main.js
// the data should be in object format
var car = {
  model : 'GLA-200',
 color : 'White',
 price : null
}
// the data would pass to the worker
anyWorker.postMessage(car); 
This above code sends the car object to the worker.

This car object can be found at worker file by doing something like
anyJsFile.js
onmessage = function (e){
 var wCar = e.data;
 wCar.price = '$70000';
 wCar.company = 'Mercidies Benz';
 postMessage(wCar);
}
After modified the car object you can pass the modified object by postMessage(wCar) method  to main thread(main.js)

By the following code, you can get that modified data as e.data on main thread with onmessage method

anyWorker.onmessage = function (e){
 // get modified object from worker
 var mcar = e.data; 
 console.log(
 'Car model is ' + mcar.model + '\n' + 
 'Car color is ' + mcar.color + '\n' + 
 'Car price is ' + mcar.price + '\n' + 
 'Car company is ' + mcar.company + '\n' 
 );
}


The below points are worth to read

Same Origin Policy

The worker file and the code for an attempt to using that worker should be placed in same origin policy. Like anyWorker.js and main.js file should be located under same domain like http://javascriptfuture.com

DOM/BOM

The BOM(browser object model) and DOM(document object model) are not available for the web worker.

You can find the working example with Web-worker.