Javascript DOM Manipulation to improve performance
Tags: frontend, javascript, html, webdev
Published: 2019-01-25 23:16:12

---
title: Javascript DOM Manipulation to improve performance
published: true
description: Improve performance when using Vanilla Javascript
tags: frontend, javascript, html, webdevelopment
cover_image: https://thepracticaldev.s3.amazonaws.com/i/n126xy4eeppznicca4ps.png
---
I wrote this article to show you with examples, how avoid performance issues when develop Web Applications with Vanilla Javascript.

### Use selector instead nested elements

```sh
// BAD
let menu = document.querySelector('header > nav > ul.menu');

// GOOD
let menu = document.querySelector('.menu');
```

### Avoid DOM manipulations inside loops

```sh
// BAD
for (let i = 0; i < 10; i++) {
    document.querySelector('.numbers').innerText += i;
}

// GOOD
let numbers = '';
for (let i = 0; i < 10; i++) {
    numbers += i;
}
document.querySelector('.numbers').innerText = numbers;
```

### Don't use DOM values inside loops

```sh
// BAD
let nodes = document.querySelectorAll('.menu-items');
for (let i = 0; i < node.length; i++) { ... }

// GOOD
let nodes = document.querySelectorAll('.menu-items');
const size = nodes.length;
for (let i = 0; i < size; i++) { ... }
```

### Use css classes instead inline styles

```sh
// BAD 
let card = document.querySelector('.card');
card.style.width = '400px';
card.style.color = '#f0f0f0';
card.style.marginTop = '10px';

// GOOD 
let card = document.querySelector('.card');
card.style.cssText = ''.concat(
    'width       : 400px;',
    'color       : #f0f0f0;',
    'margin-top  : 10px;'
);

// BETTER 
.card-custom {
    width: 400px;
    color: #f0f0f0;
    margin-top: 10px;
}

let card = document.querySelector('.card');
card.classList.add('card-custom');
```

### Appending DOM is the most expensive operation, choose the right approach

```sh
// BAD
let container = document.querySelector('.container');
for (let i = 0; i < 1000; i++) {
    let a = document.createElement('a');
    a.text = `Row N° ${i}`;
    container.appendChild(a);
}

// GOOD
let container = document.querySelector('.container');
let html = '';
for (let i = 0; i < 1000; i++) {
    html = html.concat(`<a>Row N° ${i}</a>`);
}
container.innerHTML = html;

// BETTER
let a = document.createElement('a');
let container = document.querySelector('.container');
for (let i = 0; i < 1000; i++) {
    let cloneA = a.cloneNode(true);
    cloneA.text = `Row N° ${i}`;
    container.appendChild(cloneA);
}

// BETTER^2
let a = document.createElement('a');
let container = document.querySelector('.container');
let documentFragment = document.createDocumentFragment();
for (let i = 0; i < 1000; i++) {
    let cloneA = a.cloneNode(true);
    cloneA.text = `Row N° ${i}`;
    documentFragment.appendChild(cloneA);
}
container.appendChild(documentFragment);
```

### Use innerHTML only for first rendering and then use DOM methods

```sh
// BAD
let container = document.querySelector('.container');
container.innerHTML = '<input type="text" name="example" value="Hi DEVS!">';
container.innerHTML = '<input type="text" name="example" value="Bye DEVS!">';

// GOOD
let container = document.querySelector('.container');
container.innerHTML = '<input type="text" name="example" value="Hi DEVS!">';
let input = container.querySelector('input');
input.value = 'Bye DEVS!';

```

If you have some tips, please leave your comment. 
Keep calm and code!