Search This Blog

2024/04/01

Javascript:Code Optimization tricks


 Convert to floating number:
Often we use Math.floor, Math.ceil and Math.round for eliminating decimals.
Instead of using them use “~~” to eliminate decimals for a value.

Usual Way:
let y = Math.round(Math.random() * 100);
console.log(y);


Optimized Way:
let x = ~~(Math.random() * 100);
console.log(x);s

Using length to delete empty in an array:
For deleting n elements in an Array, use array.length.

Usual Way:
let array = [1, 2, 3, 4, 5, 6];
array =[];


Optimized Way:
let array = [1, 2, 3, 4, 5, 6];
array.length =0;

Cache the variable:
Caching the variable tremendously increase javascript performance.
JavaScript code may involve repeated operations or function calls that
consume resources unnecessarily. By caching the results of these operations,
we can avoid redundant calculations and improve performance.

Code (Without Caching) :
function calculateFactorial(n) {
if (n === 0 || n === 1) {
return 1;
} else {
return n * calculateFactorial(n - 1);
}
}

Code (With Caching) :
let factorialCache = {};
function calculateFactorial(n) {
if (n === 0 || n === 1) {
return 1;
} else if (factorialCache.hasOwnProperty(n)) {
return factorialCache[n];
} else {
let result = n * calculateFactorial(n - 1);
factorialCache[n] = result;
return result;
}
}

Loop Optimization:
Efficient looping can have a significant impact on the performance of
JavaScript code. Some techniquesfor optimizing loops include minimizing
function calls inside loops, reducing unnecessary iterations,and using
more efficient looping constructs.

Usual Code:
// Original Loop
for (let i = 0; i < array.length; i++) {
doSomething(array[i]);
}

Optimized Code:
// Optimized Loop
const length = array.length;
for (let i = 0; i < length; i++) {
doSomething(array[i]);
}

Note:
In this example, we store the length of the array in a variable
(length) before the loop to avoid retrieving it repeatedly during
each iteration. This optimization prevents unnecessary property
lookups and improves performance.

Use switch case instead of if/else:
Generally switch cases are used over if/else statements to perform almost
the same tasks.

The fact that in switch statements expression to test is only evaluated once,
execution time becomes less for the script compared to if/else where for every
if , it has to be evaluated.

Avoiding String Concatenation in Loops:
String concatenation inside loops can lead to inefficient code due to the
immutable nature of strings in JavaScript. Instead of using concatenation
operators (+), it is more efficient to build an array of strings and join
them using the join() method.

Usual Code:
let result = '';
for (let i = 0; i < array.length; i++) {
result += array[i];
}

Optimized Code:
let result = [];
for (let i = 0; i < array.length; i++) {
result.push(array[i]);
}
result = result.join('');

Note:
By pushing the strings into an array and using join('') at the end, we
minimize the number of string concatenations and achieve better
performance.

Using Object/Array Destructuring:
Object and array destructuring is a feature introduced in ECMAScript 6 (ES6)
that allows you to extract values from objects and arrays into individual
variables. It can enhance code readability and improve performance by reducing
the number of property or index lookups.

Usual Code:
let firstName = person.firstName;
let lastName = person.lastName;

Optimized Code
let { firstName, lastName } = person;

Swapping variable:
We can use third variable to swap to array but Es6 let you do it using
destructering which is more readable & improves performance.

Usual Code:
let swap =array[index]
array[index] = array[i]
array[i] = swap

Optimized Code:
[array[index], array[i]] = [array[i], array[index]];

Merging arrays:
Using Array.concat() function on large arrays will consume lot of memory
while creating a separate new array.

Usual Way:
var array1 = [1, 2, 3];
var array2 = [4, 5, 6];
var array3 = array1.concat(array2);
console.log(array3); // [1,2,3,4,5,6];


Optimized Way:
var array1 = [1, 2, 3];
var array2 = [4, 5, 6];
array1.push.apply(array1, array2)
console.log(array1);

Caution:
Even though we are comparing this two codes they are not doing same
thing. Array.concat() creates new result array while Array.push will
push result into existing array.

Use splice to delete array elements:
delete is good for deleting attributes of objects, but not so good for arrays.
It is better to use splice for arrays.When we delete an element from array it
will remove that item but keep empty slot so effectively array length will be
same as previous one.For such a array obtained after deleting. Indexed for
loops would crash, since indexes are no longer sequential.you should use for
each loops when you need to loop through arrays.

Usual Code:
let myArray = ["a", "b", "c", "d"]
let firstRemoved = delete myArray[0]
let secondRemoved = delete myArray[1]
console.log(myArray)
console.log(myArray.length)

Optimized Code:
let myArray = ["a", "b", "c", "d"]
let firstRemoved = delete myArray[0]
let secondRemoved = delete myArray[1]
console.log(myArray)
console.log(myArray.length)

Notes:
Consider code below

Code:
let myNewArray = ["a", "b", "c", "d"]
delete myNewArray[0]
delete myNewArray[1]

console.log('Indexed For Loop:')
for(let i=0;i < myNewArray.length;i++){
console.log(myNewArray[i])
}

console.log('ForEach Loop:')
myNewArray.forEach((m)=>{
console.log(m)
})

Output:
Indexed For Loop:
undefined
undefined
c
d
ForEach Loop:
c
d


Here forEach loop will ignore empty slots in between array created by
deleting some middle elments in array using 'delete'.

Short-circuits conditionals:
Short circuiting is when a logical operator doesn't evaluate all its arguments.
Short-circuits conditionals

Usual Code:
let loggedin = false;

function callMe() {
console.log("Hello World");
}

if (loggedin) {
callMe()
}

Make it short by using combination of a verified variable and a function
using && (AND operator) in between both.

Optimized Code:
let loggedin = false;

function callMe() {
console.log("Hello World");
}

loggedin && callMe()

Getting the last item in the array:
Array.prototype.slice(begin, end) is used to cut arrays when you set the start
and end arguments.But if you don't set the end argument, this function will
automatically set the max value for the array. parameter of Array.slice can
also accept negative values it will give the last elements from the array.

Code:
var array = [1, 2, 3, 4, 5, 6];

console.log(array.slice(0,1)); // [1]
console.log(array.slice(0,2)); // [1,2]
console.log(array.slice(0,)); // [ 1, 2, 3, 4, 5, 6 ]
console.log(array.slice(1,));//[ 2, 3, 4, 5, 6 ]

console.log(array.slice(-1)); // [6]
console.log(array.slice(-2)); // [5,6]
console.log(array.slice(-3)); // [4,5,6]

Output:
[ 1 ]
[ 1, 2 ]
[ 1, 2, 3, 4, 5, 6 ]
[ 2, 3, 4, 5, 6 ]
[ 6 ]
[ 5, 6 ]
[ 4, 5, 6 ]

Default values using || operator:
In JS there is a basic rule of having a default value otherwise process will
halt at undefined values.To provide default value in a variable use || to
stay away from this most common issue.

var a = a || 'hello'

Using String replace function to replace all the values:

The String.replace() function allows you to replace strings using String
and Regex.Basically this function replaces the string at its first
occurrence. But to replace all using replaceAll() function, use /g at
the end of a Regex:

Usual Code:
var string = "login login";
console.log(string.replaceAll("in", "out"))

Optimized Code:
var string = "login login";
console.log(string.replace(/in/g, "out")); //"logout logout"

Note:
Now as far as the performance is concerned, the replace() method is a
bit faster than replaceAll() because the latter first compiles the
regex pattern and then matches before finally replacing whereas the
former simply matches for the provided argument and replaces.

Since we know the regex pattern matching is a bit more complex and
consequently slower,then preferring replace() over replaceAll() is
suggested whenever possible.

Minify JavaScript code for smaller file sizes:
Minifying code is different from obfuscating code, but both are methods of
transforming JavaScript—to be more difficult to read, or to make it smaller.
Minification accomplishes the latter, and can shrink file sizes to decrease
page load times.

Line breaks, additional spaces, comments etc.—all of this increases the size
of a JavaScriptfile and affects the speed of page load. Compressing the code
solves this issue well. Machines are not sensitive to the visual style of code
like a human would be. Computers can read and launch minified code, even if
all of your Javascript fits in just one string.

Optimize Javascript with minification:
Optimization is a special type of JavaScript minification. These kind of
minimizers not only delete unuseful white spaces, commas, comments etc. but
also help to avoid “dead code”:

Common Tools:
Google Closure Compiler
UglifyJS
Microsoft AJAX Minifier

Before Optimization:
function test(node) {
var parent = node.parentNode;
if (0) {
console.log( "Hello from the other side" );
} else {
console.log( "We love Upwork" );
}
return;
console.log( 1 );
}

After optimization:
function test(){
console.log("We love Upwork")
}


Note:
What exactly did optimization accomplish here?
1) The variable parent will never need to be used, so it gets
deleted;
2) False if() {…} is deleted as ‘dead code’; true else leaves only
one possibility.
3) Return is deleted; it’s also dead code.

No comments:

Post a Comment