Like any kind of apps, JavaScript apps also have to be written well.
Otherwise, we run into all kinds of issues later on.
In this article, we’ll look at some best practices we should follow when writing JavaScript code.
The Spread Operator and Arrays
The spread operator can do many things.
We can use them to merge arrays.
For instance, we can write:
const a = [1, 2, 3];
const b = [4, 5, 6];
const c = [...a, ...b];
c
has all the entries of a
and b
.
We can also spread an array into a function as its arguments.
For example, we can write:
const sum = (x, y, z) => x + y + z;
const nums = [1, 2, 3];
const total = sum(...nums);
We use the spread operator spread the nums
entries as arguments.
Defer the Loading of Scripts
We can defer the loading of scripts with the defer
attribute.
This way, they’ll load asynchronously in the order they’re listed.
For example, we can write:
<script defer src='script.js'></script>
We can also put script tags at the end of a file so that they load last.
Save Bytes by Using Minification
Before we deploy our app to production, we should minify them so that we reduce the package size.
If we use frameworks, this should be done automatically by the CLI program for those frameworks.
If we don’t we can use Parcel or Webpack to do the modification for us.
Avoid Unwanted Loops
We should avoid nested loops to keep our code linear.
Also, we don’t want our loop to go through many objects since it’ll be slow.
Prefer Map Over for Loop
If we’re mapping array entries from one thing to another, we can use the array instance’s map
method.
This way, the original array doesn’t change.
The scope is isolated since the mapping is done with a callback.
It’s also shorter than a loop.
And we can compose with other operations like loops and other array methods.
For instance, we can write:
let strings = ['1', '2', '3', '4', '5'];
const total = strings
.map(str => +str)
.filter(num => num % 2 === 1)
.reduce((sum, number) => sum + number);
to convert the strings
entries to numbers with map
.
Then we call filter
to return the odd numbers from the mapped array.
And finally, we call reduce
to get the total of the odd numbers.
With loops, this is much longer.
We’ve to write:
let strings = ['1', '2', '3', '4', '5'];
let nums = [];
let oddNums = [];
let total = 0;
for (const s of strings) {
nums.push(+s);
}
for (const n of nums) {
if (n % 2 === 1) {
oddNums.push(n);
}
}
for (const o of oddNums) {
total += o;
}
We have 3 loops to do the mapping, filtering, and adding respectively.
It’s just much shorter to use array instance methods.
Use Proper Event Handlers
We can use event handlers by using event delegation to check for what DOM element triggered the event.
Also, we should remove them when we’re done with the with removeEventListener
.
To do event delegation, we can write:
document.addEventListener('click', (e) => {
if (e.srcElement.tagName.toLowerCase() === 'div') {
//...
}
})
to check for clicks for divs.
To call removeEventListener
, we can write:
target.removeEventListener('click', onClick);
where onClick
is an event listener function.
Remove Unused JavaScript
If we have unused code, then we should remove them.
This way, no one will be confused about them.
Avoid Using Too Much Memory
Every time our code uses more memory, the garbage collector will be run when to clean up unused resources later.
If garbage collection runs frequently, then our app runs slowly.
So we should avoid reserving memory in the first place.
Cache in the Browser
We can cache things with service workers.
We can cache things with the Cache API.
To add caching, we can write:
const CACHE_VERSION = 1;
``const CURRENT_CACHES = {
font: `font-cache-v${CACHE_VERSION}`;
};``
self.addEventListener('activate', (event) => {
let expectedCacheNamesSet = new Set(Object.values(CURRENT_CACHES));
event.waitUntil(
caches.keys().then((cacheNames) => {
return Promise.all(
cacheNames.map((cacheName) => {
if (!expectedCacheNamesSet.has(cacheName)) {
return caches.delete(cacheName);
}
})
);
})
);
});
We delete data from the cache by looping through the keys and checking for items that aren’t named in CURRENT_CACHES
.
Conclusion
We can use modern features like service works and spread operator to help us make our app better.
Also, we should keep performance in mind with a few things to look for.