jQuery vs getElementById vs querySelector

Last time we talked about performance in JavaScript and how that can be measured. To better illustrate the usage of the performance.now function and how it can be used to help us decide which method we should use to accomplish a certain task in our code, this time we will test the 3 most common methods of selecting a specific DOM element:
• jQuery’s $() selector is probably the most common and the first one that comes to mind
• document.getElementById is the classic method and perhaps the function that most JS developers are taught first
• document.querySelector is a relatively recent addition to the DOM API that’s supported by the latest browser versions out there

Test Case
Obviously the selection of one single DOM element is very rapid so it’s not the best of ways to test for the efficiency of those 3 methods. We’re talking about an operation that takes nanoseconds (or even less..) to finish. So even if we had the means to get test data about such a small timeframe it still wouldn’t be a fair comparison since there countless of factors affecting the final result, like different browser threads or even different processes running on the system. To get a better understanding we need to enlarge our test pool. For that, in the following example we will use a for loop to spawn 10 thousand buttons, append them to the DOM tree and them we will use the 3 methods mentioned above to select all the buttons, one button at a time using for loops. So we want to end up to something like the following pseudocode:

var t0 = performance.now();
for(1 to 10000){
	//select using jquery
}
var t1 = performance.now();

var t0 = performance.now();
for(1 to 10000){
	//select with document.getElementById
}
var t1 = performance.now();

var t0 = performance.now();
for(1 to 10000){
	//select with document.querySelector
}
var t1 = performance.now();

After the tests are done, hopefully we’re going to have a clear answer as to which one of these methods we should use to speed up our script’s execution.

The Button Spawnner

The following is a simple algorithm used for spawning a button with id ‘id’, inside ‘container’ with text content ‘contents’:

We want to spawn quite a lot of buttons so let’s just start by placing a constant at the top of our script and set the number of buttons that we want to create. That way, if 10 thousand isn’t enough for us to reach a verdict we can return and change the number of buttons from a single point in our code:

const BTN_NUM = 10000;

We will also need a container div to host the remarkable amount of buttons we’re about to create:


<div id="mydiv">    
    
</div>

We select the div element using getElementById (or maybe we should use jQuery, it might be faster, or querySelector, anyway we’ll see in a moment 😛 )

let myDiv = document.getElementById('mydiv');

We also need to introduce a naming scheme for the 10k buttons so that we don’t have a hard time selecting them from the inside of a loop. It doesn’t have to be something complex. “btn-i” where ‘i’ is the incremented value will do just fine. So let’s spawn the buttons!!

let idPrefix = "btn-";
for(let i=0; i<BTN_NUM; i++){
	let name = idPrefix + i;
	spawnButton(name, myDiv, "Button");
}

If you run the script at this point, your browser window will fill with buttons capable of causing a seizure to people with light sensitivity but bear with me a little while longer and we’ll soon know which is the fastest method.

Let’s declare some required variables for our tests:

let t0, t1, jQueryPerformance, getElementPerformance, querySelectorPerformance;

And start them finally:

Running the tests I got these results (I ran each test three times to get a more definitive answer):

Google Chrome

chrome

Mozilla Firefox

firefox

Microsoft Edge

 

edge

 

Measuring code execution performance in JavaScript

Performance Considerations

Developers and especially JavaScript developers can be extremely indecisive. “I’ve found multiple ways to achieve the same thing but which one is the fastest, the most appropriate? Which one is the optimal one?” Most of us would relate to such questions and although there is no definitive answer to which method you should choose, there are ways to make your struggle to reach a verdict a lot easier. One of the factors that will greatly affect your choice is the overall speed of the program. That’s not the only factor as others come into play, like cleanness, maintainability and speed of development but speed and efficiency are very important nonetheless.

How to measure time in JS

In the past the most prevalent method to take time measurements was new Date().getTime. However that approach was quickly abandoned as more features were added to the language. Console.time provided a nice alternative. Console.time is pretty simple. You just specify a string name for the timer and call the method to start counting. After the code you want to check has finished executing you call the method again providing the same name as the first and only argument:

console.time("mycode");

//code that takes some time

console.time("mycode");

The result gets printed in the console like this:

mycode: 355ms

Unfortunately Console.time (as you can read in its MDN page) is no longer standard and it’s use is therefore heavily discouraged.

Date().getTime is deprecated, console.time is non-standard, so how can I measure my code’s execution time?

When it comes to raw performance measurement in JavaScript performance.now is the way to go. The Performance interface contains various performance related methods (duh!) you can use to take measurements for time-related stuff. Now() is the interface’s method you will probably use the most and this method is the one described in this post.

.now()

 

The method’s functionality is pretty simple and straight-forward.
The Performance.now() method returns a DOMHighResTimeStamp, measured in milliseconds, accurate to one thousandth of a millisecond. (thanks MDN <https://developer.mozilla.org/en-US/docs/Web/API/Performance/now> ).




let timeBefore = performance.now()



someMethod();



let timeAfter = performance.now()



let diff = timeAfter - timeBefore;



console.log("Diff: " + diff);



To demonstrate the use of performance.now in a more real-life example let’s count how much time it takes to fetch 5000 photos from JSONPlaceholder (https://jsonplaceholder.typicode.com/)

We declare timeBefore right before calling fetch and timeAfter right after the data has been parsed and printed to the console window. The result gets also printed in the console.

You can see the results of three consecutive executions in the next screenshot (Google Chrome):

untitled-1

Advanced JavaScript object control

Last time we talked about property descriptors and how we can use them to properly manipulate object properties to make them suit our needs as effectively as possible. In this post we are going to talk about some built in methods that can make our life with objects and their property descriptors much easier. Note that all the functions mentioned below operate on the object level. They apply to all properties and not just to one like property descriptors (link to article).

Let’s start with preventExtensions. This function will take your object and make its list of properties immutable. That means the function will disallow any further property additions to the object. If you try to add a property to that object afterwards the result will depend on the strictness of the code. In non-strict mode the property simply won’t be added, the program execution will continue as it otherwise normally do but the property won’t be added. So if you try to access it, you will get back the value ‘undefined’. In strict mode you get a TypeError. Check the following example that briefly demonstrates this useful functionality:

Note that preventExtensions does not protect the property’s against deletion. We successfully managed to delete the property ‘a’

The same example in strict mode:

If you try to execute this piece of code you will never get past line 13. The code will fail with this very descriptive error line: ‘Uncaught TypeError: Can’t add property d, object is not extensible’

preventExtensions is pretty useful when combined with strict mode because it gives you full control of your object’s lifetime. For example, say you have created a module that returns an object that for whatever reason you won’t to stay with its current properties. You can protect it with preventExtensions and any attempts to add unwanted properties will crash the script.

Next in line is seal. This function builds on top of preventExtensions to further protect your object’s properties. What seal does is it calls preventExtensions but also disables the configurability of every property. You can get the same result if you call preventExtension on your object and then modify the descriptor of every property and set configurable to false.

Check the following example, after the object is sealed we cannot add or remove any properties:

The last function for today is Object.freeze(). This function essentially calls Object.seal() on the object while also setting the writable status of every property to false. So that way you end up with a fully immutable object. See the example for more:

Of course if we try the same code in strict mode we will receive a TypeError when trying to add a new property.

That’s it for today. Three useful functions for full control of your objects. I hope you liked it and found it helpful. Check more JavaScript stuff here.

Function Expressions vs Function Declarations In JavaScript

Hello everyone! Today I’m going to talk to you about function expressions, function declarations what’s best to use, when to use and more importantly how to avoid unexpected behavior when using them. A lot of newcomers to JavaScript find this confusing but I’m here to convince you that it’s pretty simple:

This is a function declaration:

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

This on the other hand is a function expression:

var foo = function(){
	console.log("I am foo");
}

In either case you execute foo in the same way:

foo();

The same thing applies if foo takes one ore more parameters:

function foo(param1, param2){
	….
}

var foo = function(param1, param2){
	….
}

Then you can call it like this:

foo("bar", 3.14);

So I can use whatever I like best and there is no real difference between the two besides the syntax used during the function definition?
The answer is No

Consider the two following examples:

Example 1:

foo();

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

Output: “I am foo”

Example 2:

foo();

var foo = function(){
	console.log("I am foo");
}

Output: Uncaught TypeError: foo is not a function

Why is this happening? The reason has to do with hoisting. When you use a function declaration you can imagine that during the first pass of the compiler the function and variable declarations will be moved to the top of the enclosing function (that’s not exactly what really happens but it’s very convenient to imagine it like that). When you use a function expression, only the variable declaration will be “moved” to the top of the enclosing function. You can visualize the result of hoisting in both examples like this:

Example 1 (after hoisting):

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

foo();

Example 2 (after hoisting):

var foo;

foo();

foo = function (){
	console.log("I am foo);
}

As you can see in the second example when the engine executes the statement ‘foo();’ it does not possess sufficient knowledge about foo. At that time it only knows that foo is a variable, the actual assignment takes place later in the code.

This is actually the most important thing between function declarations and function expressions

Hoisting

Ok so this is going to be a short one. I recently stumbled upon a question in StackOverflow (actually include a link here) that was asking something like this:

Why is this code valid?

//Start of this file
myFavoriteMovie = "Star Wars"
console.log(myFavoriteMovie);   //Actually prints 'Star Wars' even though `myFavoriteMovie` is undeclared
.
.
.
// A few more lines of irrelevant code
.
.
.
var myFavoriteMovie = "Inception";   //myFavoiteMovie declared
console.log(myFavoriteMovie);

So what do you think would be the output of this script?
Most people would say that an error will be shown claiming that `myFavoriteMovie` is undefined or that `undefined` will be printed in the console. The strange thing is, that the same people that find this code wrong, will find the following code fine:

var game = new VideoGame("Mass Effect", "Bioware", "Action RPG");
console.log(game);

function VideoGame(title, developer, genre){
	this.title = title;
    this.developer = developer;
    this.genre = genre;
}

Those two examples are essentially the same thing. In the first example, `myFavoriteMovie` is used before declaration. In the second example, the same thing happens with the VideoGame function. It’s used before declaration but few people notice the similarity. I too, could not see it and I was surprised when I found out. I think the source of confusion for most of us is that using a variable before declaration is counterintuitive, it’s something that we normally do not do and if we do it’s probably by mistake. However, defining a function or a class at the end of a file and using it before declaring it is rather common because it helps some developers (including me) with code organization. But using a variable before declaring seems off to the most of us. Perhaps that’s because most of us started coding in a more strict language than JavaScript, C for example where it is unthinkable to use a variable before declaring it.

Anyway, there is a name for this and that’s Hoisting. It’s something that happens every time you run your JavaScript script (or just JavaScript 😛 ). Hoisting is the process of moving all variable, function and class declarations found in the file, at the start of that file. So right before execution the code of the first example gets transformed and ends up looking like this :

var myFavoriteMovie = "Inception";
myFavoriteMovie = "Star Wars";
Console.log(myFavoriteMovie);
.
.
.
// A few more lines of irrelevant code
.
.
.
myFavoriteMovie = "Inception";
console.log(myFavoriteMovie);

That is why you can use variables, functions, classes and objects before you actually declare them.

Hope you find this explanation of JavaScript Hoisting helpful. Check more awesome JavaScript stuff here