Beginner’s JS – Week 3 & 4

It was a big difficult jumping back into the Javascript course again because since my last update I flew to PAX South in San Antonio, Texas, caught an extremely nasty case of ConCrud (convention sickness), and then flew up to Omaha, NE for one of our quarterly Flywheel work retreats, however I then caught influenza and was out sick for week with a sinus infection following that, it’s been a rough freakin month, I’ll leave it at that. BUT, I’m starting to recover finally now that it’s the middle of February and I’m ready to dive back into more Javascript stuff 🙂

Browser Performance & Repaints

One of the interesting topics covered in module four was on the subject of browser performance, something near and dear to my heart. Specifically, it lightly covers the topic of “painting” which is when an alteration is made to the DOM on the browser, which the browser then needs to go through and “repaint” the layout of the page since elements within the existing structure have changed. Generally speaking you want to avoid repaints from your Javascript as much as possible if you’re doing DOM manipulation since it essentially makes the browser redo all of it’s work a second time. It’s hard to manage, admittingly, but something to be aware of is the rule of thumb of “measure twice, cut once”, which applied to browsers can be transformed into “do all your calculating first, then only apply changes to the DOM once”.

An example of a repaint might look something like this next example, where we Add a child to the DOM (repaint 1), then add a new paragraph (repaint 2), then we add a new image (repaint 3), which forces the browser to repaint upwards of three times, which is no good:

// Add a div with a paragraph and image inside of it to the DOM
document.body.appendChild(myDiv);
myDiv.appendChild(myParagraph);
myDiv.appendChild(myImage);

However, this approach reflows the page 3 times in a row, once per append child as we add more and more items. This can cause jankiness, performance issues, and weird animation. To fix this, you’ll just want to ensure that only one item is added to the DOM at once, and then it’s updated as infrequently as possible. This can be done by adding all of the children to the parent within Javascript, then adding the entire HTML with all appends to the DOM at the same time in one swoop instead:

// Only one paint since we add to the DOM once at the end
myDiv.appendChild(myParagraph);
myDiv.appendChild(myImage);
document.body.appendChild(myDiv);

Speaking of placing content into the DOM

One of the coolest parts of these sections was the introduction of a new ability in ES6 I haven’t been exposed to before called the `.insertAdjacentElement()` API. It is super slick for letting you control where you want elements to be inserted, allowing you to insert the before the target, inside the target at the top, inside the target at the bottom, or after the target. This simplifies things greatly compared to simply `.append()` or `.appendChild()` and gives us a lot more accuracy.

Another small takeaway

In the final “DOM Cardio” section of the fourth module, Wes mentions in passing the existence of something which blew my mind. In the course you’re tasked with creating a button on a series of cards and if the button is ever pressed it removes the card it’s within. The task is simple enough and illustrates some core principles that had been covered in the course leading up to this point, but the part which fascinated me is how the function is able to find which button was pressed (and therefore which card to delete).

For context, in the past we’d often need to set up a lot of information to then pass into functions before you could run them, so if we needed to find which “card” to delete, we’d first have to identify which button was pressed and then pass its specific button element information into the function as an argument so that the function could accurately make adjustments to the correct button that was pressed.

TURNS OUT that you can just call event.currentTarget inside of the function and it returns to you the element which triggered the eventListener, so there’s no need for complicated argument passing or anything, you can simply say “hey function, what was your target?” and the function just knows that implicitly and you can move on with your day without being all sweaty and clogging up your code with frivolous arguments. This might seem like a super small thing (and as a full disclaimer: I have no idea how long event.currentTarget has existed, but in my 5 year history of dabbling with javascript this might be the one thing which just blew my mind the most because it was such a headache every time I’ve tried to work with functions like this in the past and I’ve never been exposed to it).