Warning: Uninitialized string offset 0 in /var/www/drunkenux.com/public_html/wp-includes/bookmark-template.php on line 1

Warning: Uninitialized string offset 0 in /var/www/drunkenux.com/public_html/wp-includes/bookmark-template.php on line 1

Warning: Uninitialized string offset 0 in /var/www/drunkenux.com/public_html/wp-includes/rest-api/endpoints/class-wp-rest-revisions-controller.php on line 1

Warning: Uninitialized string offset 0 in /var/www/drunkenux.com/public_html/wp-includes/rest-api/endpoints/class-wp-rest-revisions-controller.php on line 1

Warning: Uninitialized string offset 0 in /var/www/drunkenux.com/public_html/wp-includes/rest-api/endpoints/class-wp-rest-settings-controller.php on line 1

Warning: Uninitialized string offset 0 in /var/www/drunkenux.com/public_html/wp-includes/rest-api/endpoints/class-wp-rest-settings-controller.php on line 1

Warning: Uninitialized string offset 0 in /var/www/drunkenux.com/public_html/wp-includes/blocks/navigation.php on line 1

Warning: Uninitialized string offset 0 in /var/www/drunkenux.com/public_html/wp-includes/blocks/navigation.php on line 1
#110: Raising the Curtain on JavaScript Performance – The Drunken UX Podcast
The Drunken UX Podcast

#110: Raising the Curtain on JavaScript Performance

Despite the growing abundance of bandwidth and computing power available from desktops to cell phones, putting attention on the performance of the code you write is still a worthwhile skill to cultivate that will help you avoid issues down the road. This week we’re getting our hands dirty looking into techniques that will help you identify issues that will impact your code’s performance so that your next project comes out as sleek as possible.

Followup Resources

Transcript

The following is a machine-generated transcript of this episode. It will contain errors until it has been reviewed and edited, and we apologize for the difficulty that may cause for screen readers. Do you want to help us speed up our transcribing process? Consider sponsoring an episode.

Well hello ladies and germs, this is The Drunken UX Podcast. I am your host, Michael Fienen. This is episode number 110 for March 14, 2022.

Did you say ladies and germs?

Ladies and germs. I know

are i Good? Evening?

Well, good morning, it’s a Michaels on a little bit of an adjusted schedule due to a show that he is doing in the evenings. And so our recording has had to shift is bright and early. Let’s say we are this week in this episode in this podcast bit talking about JavaScript performance, we’re going to get into a few techniques, tips, tricks, things like that. Also, if you haven’t yet, go back and listen to our episode on dev tool tricks, because this is going to include a little bit of that. And some things we didn’t talk about in that episode, because dev tools, believe it or not really handy for figuring out JavaScript performance.

So come back, listen to that. We’ll wait here or do it afterwards, whatever. But be sure to become one of our fantastic Patreon backers at drunken ux.com/support Join the group over there and give us a yell and say, Hey, this is what I’d like to hear. And we get that probably queued up very quickly for you.

Let’s see. Outside of that. Coffee,

lots of coffee second Coffee of the morning. I know not Irish coffee. Not.

No, it’s fine. So

just coffee.

I’m also medicated, I hopefully I’ll be more on point because I’ve just taken my medication so my brain will be

fresh and why and prickly, prickly brain.

Although I would say that, this is going to be definitely like more of your wheelhouse here. So I’ll just be asking a lot of questions.

Hey, I’m gonna teach you, we all have stuff to learn. And that is just all right. I just took a drink of my coffee. And for folks who’ve never seen me in the real meat space, I have a giant beard and mustache and it’s a whole thing. And I I said prickly brain. And when I when I popped that P I saw myself in the camera and coffee just sprayed. It is a problem. Oh my god, I gotta I gotta swallow that pee a little bit when I say it. Okay, let’s dive in.

Let’s Oh, sounds wrong, dude.

I will Hey, I, you know, I tried waxing it off to the sides a little bit this morning. It’s easy to swallow that be Oh, that’s a dope, kink shame. And. And it’s not my thing. But as I swallow coffee, let’s jump into JavaScript performance of first and foremost. So why well, let’s let’s real quick hit on why this is important. And I think we’ve kind of gotten into this a few times in the world of build processes in the world of application development, and node and react and all of these things and view and all of these libraries and different approaches to client side work and server side work.

One of the things is, we have been spoiled by the amount of CPU power we have. And so the spoils, there is I think, a inclination for folks to over engineer things. Oh, we’re gonna use this library. And it includes all of this other stuff, and no big deal. Oh, you mean the JavaScript files? 732 kilobytes. So what? That’s not that much.

I have a slightly different take on that. I think that because it’s not just JavaScript. It’s everything right?

It’s everything. Sure. Yeah.

I mean, they they sent the they sent the Apollo 12 To the moon with like, 132 kilobytes or something, if something we can tiny. And I think that computing power has made us lowercase L lazy. I not in a bad way, but in a way that we don’t have to concern ourselves with things like memory allocation, and pointers and stuff that can all be handled, which lets us deal on a more abstract level. And I think that being able to deal at a more higher level of abstraction affords us more like latitude with the kinds of things we can do, which is really cool.

Like you wouldn’t be able to have a So JavaScript sitting on top of whatever your web browser is made in, which is sitting on top of probably C libraries, which is sitting on top of assembly, and then down on to machine code. That wouldn’t be possible if we still had these punch cards, you know? Yeah. In on one

hand, there are a lot of ways and this goes to computing in general, not just web development, but this notion of Yeah, we don’t have to concern ourselves with XY and Z in order to make a functional product, whatever that product may be. And now I’m saying that not because I believe it, but because I think that is the prevailing sort of theory that is traded in different spaces. Why this is a problem, because it’s easy to say things like, oh, but you know, there are still people on very low power devices, or Oh, mobile devices, you know, that, you know, they’re on cell networks.

And all of this, and the counterpoint people are gonna say is, yeah, but even cell phones are getting wildly powerful, their battery life is ever increasing, network speeds are ever increasing. So it’s just going to catch up to the same point. So why Why worry about these things? To which I say, first and foremost, it is a matter of refinement, it is a matter of professionalism, and quality of product. Caring about those things, is what really differentiates, you know, a senior developer from a junior or associate developer, but more importantly, it’s how we prevent mistakes from happening.

You know, if you have no sense whatsoever of memory handling and garbage collection, and you’re just writing code and letting objects grow, and because of the way you’ve scoped it to the window and bound properties, that stuff never gets cleaned up, or garbage collected or anything like that. You risk introducing security vulnerabilities. Do you want bugs that take it bugs? Do you want bugs, that’s how you get ants. That’s really, I think the big problem is when you have badly optimized code, you create surface area for things like attacks, you create opportunity for problems, maybe not attacks, but ways for things to fail unexpectedly,

I actually started looking at specking out a new PC, which initially began as Hey, I wonder if I can get more RAM, which I can’t, because my motherboard only has two slots. And that started because Chrome was using up so many gigs of memory, that my system was running out of swap space. And to be fair, I usually have 40 to 60 tabs open. But in this particular case, I only had maybe 10, or 20, they just happened to be high memory usage. I think even with all this computing powder power we have, I’ve got a it’s like five years old as a core i Five, it’s a decent machine, it does fine.

But when I try to use the next door, web application, you’re the one I’m talking about, oh yeah, store nextdoor.com. When I try to type stuff into that textbox it lags, like all heck. And it’s, they’re doing something I’ve not bothered to debug it because I’m not getting paid do but it’s something with how they’re doing their input field. It’s not a standard HTML input field, there’s some JavaScript, funny stuff happening. And I occasionally have that problem with Facebook to

probably some so look ahead, you know, some typing look ahead and stuff. And we’re gonna get into a little bit of this in this episode, in terms of things like event handlers, and how badly optimized event handlers can be a major problem for performance. And that’s one of those cases of like, you know, how we say all the time, you know, there’s, there are a million ways to build a house, and things like that. And it’s like, I can make code where people can write really terrible code that does exactly what it’s supposed to do, or

or third, or buying code that works at smaller scales, but becomes problematic at larger scale, large scale, you know, if you had, like, imagine you had like a JavaScript listener that just looked for a tags and did something to them, right. And on a page in your testing environment, you’re testing with, say, 108 tags. What happens if you go to like a Wikipedia article, look at that level of content, or, you know, a Facebook page load after you scroll down to infant scrolling several times, and now you have 10,000 links on the page? Yeah. It’s really easy to overlook scale, stuff like that. Yeah. Point number one.

Stop hoarding your code.

Don’t tell me what to do, man. No, I’m

telling you, this is the thing. You need to stop hoarding code

to go look at my Documents folder on my computer.

So I know DHH is a comp as it has over the last one year and a half kind of become somewhat of a content reverse shell figure a little bit

DHH if you don’t know is the guy who he runs base camp and he is the inventor of Ruby on Rails.

They’ve been Heinemeier Hansson, he’s written a couple books, things like,

he has always been a controversial, it’s probably not far off. He was, he has a lot of hot takes, I’ll put it that way. Whether you agree with them or not, they’re hot takes and he has a lot of them. And he loves talking about them. And in the last year and a half, he’s he’s had some extra nuclear hot takes. And there’s one going on right now. And that’s episode isn’t about that. But I just wanted to acknowledge that we are both aware that presently, when this episode airs, there’s still stuff happening in that community handled delicately, that but but I think you and I both agree that sometimes your faith can be problematic. And sometimes artists in the art are a separate thing as

a separate the art from the artist moment. Because I think it’s one line, it’s a one line quote, like it’s very, very easy to fire it is the greatest tool for creating good software is the delete key.

And I think that’s great. I sometimes say it as read diffs, or best stuffs. Yeah. But I agree. So artists decide, I think this is good art right here.

This is this could get very difficult and in the age before build processes, in the age of monolith flat file, JavaScript writing, just like CSS writing, it could over time get very difficult to keep track of what JavaScript you are using and what JavaScript has aged out. But you are afraid to get rid of it at that point. There is, however, a way to deal with this. Actually, there are a few ways to deal with this. Speaking of hoarding code, this literally have printed pages of code you are showing me

it’s C++ that are in high school.

So in Dev Tools, there is a panel called the coverage panel now, and I said we’re going to have some stuff in Dev Tools, that kind of references. If you don’t know how to find the coverage panel, the easy way, it’s Ctrl, Shift P that’ll open up the command palette, just type in the word coverage.

And what that does, you can go in there and between the coverage panel and the lighthouse panel, Lighthouse will flag every JavaScript file with more than 20 kilobytes of unused code on that given page, it seems that it is limited in its view, but you can use that as a way to start tracking Oh, none of this code is used on this page, and then go check another page, go check, you know, and you can start to see a profile take shape of Oh, yeah, this stuff is no longer referenced anywhere in what we’re doing. So it’s a good way of like, Lighthouse will help you identify the files.

And the coverage panel will actually show you. It’ll list out your JavaScript files, and it will list them by coverage. And it’ll show you a little bar, there’ll be blue and red, blue is code that’s being used red is code that isn’t. And then you can click on the file and it will actually highlight down the line numbers in the file. So you can see exactly it’s like not abstract, like you can go into that file and then see this is the function that is no longer used. That’s a really great way to get in. First and foremost, because it comes down to smaller files are just better to begin with, right?

When you don’t force the browser to parse through a bunch of JavaScript that it doesn’t need. It’s faster, like this is just basic, like, yeah, a shorter book is quicker to read, you know, there’s no, no magic behind it. No tricks, no anything. It’s just literally, hey, you’re making the browser do less work by saying don’t dig through all this. Similarly, you can make a file smaller just by minifying it and you can do that in your build process. There are graphical interface tools that can do that.

If you’re not comfortable with that there are browser tools pages that you can just go to and put in a file and it’ll minify it for you. I will say, if you’ve never done a build process, creating one whose only job is to just minify a file is a great starting place because it’s very, very easy. So

I have a kind of a noobish question. Is there any difference in performance or execution of a minified. JS file versus a non minified file?

Generally? No,

it’s it’s the same, right?

Yeah. minifying is all about saving space on the wire. Right? Okay. That’s what that’s all because, you know, when like, when things get parsed and stored to memory, they’re like, if you have a variable called my super long, very variable name, and then modifies the code. And when it modifies, it changes that to a, you know, like the word like a symbol or something, yeah, it will take it down to the shortest possible length string that it can do. But when the computer stores it into memory, it is stored as a memory reference. It’s not stored is just the letter A, and those memory references are all that however, you know, I don’t 16 bits long, 64 bits long.

I don’t I don’t actually know the answer to that particular question. But that’s, that’s getting into computer sciency. stuff. So in Yeah, in the JavaScript engine, that stuff all ends up being pretty much the same length from a, you know, semantic point of view. But it saves you down the wire, and sometimes that minifying I mean, it can take 2030, sometimes 40% of the size of your deal, it gets rid of all the whitespace it’ll pull out all the comments, because keep in mind, code comments are only useful to a human being.

And the only human beings that are going to care about that are the ones writing the JavaScript files, you don’t need the browser to download, you know, 800 kilobytes of code comments that you’ve put in there for for documentation, which is great. It’s super useful if you are working in space, and you need to remember, you know, you’ve got like I do J, what’s called J. S docs, which are just little code, comment blocks that go before functions. To note, what are the parameters it takes? What does it reference? What does it return? What does it do? Who wrote it. But that’s only useful to me when I’m editing.

So our build process strips all that out, which saves in some cases, those JS Doc’s are as long as the function is, you know, or longer or longer. Yeah, depending on what it is like there’s an Dincer, certainly a lot of the times, so like taking all of that out actually can be very meaningful, it also then makes the file easier to compress. Because most web servers are going to G zip that file. And the smaller minified file is going to crunch down better than that file full of whitespace full of all of those code comments that have no patterns, they aren’t the same. So like it gets, it is, it’s crunchy, or to then process down and encode. So there is actually a lot to be gained.

It also when when you work with smaller files, it reduces the amount of unorganized code you have, which isn’t necessarily a big deal for performance. But it can be a big deal to developer performance. By getting rid of all of that stuff, it’s now easier to find the things you need to find it’s easier to make sure the right stuff is grouped together or module together, things like that. So my advice minify smaller files, don’t overlook the importance of that. Okay, anyway, down the rabbit hole on that we go to the next topic is using targeted DOM manipulation.

So what’s what does this mean? JavaScript, in all of its infinite power is a fantastic tool for DOM manipulation that’s changing the way something looks right in the webpage, the document object model. We really got introduced to this by jQuery, right? jQuery says, hey, just do $1, sign a dot some parentheses and just give us a selector. And we’ll go out and we’ll find all of those things. And you don’t have to care about anything in that selector. You just give it whatever you want. The problem is, that is wildly unperformed non performance in performance.

Because it has to assume the greediest possible type of selectors. So what it’s going to do, I don’t know, like if it explicitly does this, it probably has some kind of hierarchy. But it’s effectively going to do a query selector all. And that’s great. query selector all works perfectly fine. The problem is, it’s very greedy. And it’s very resource intensive. From a JavaScript standpoint. There’s a lot of different schools of thought, especially from the CSS side about never using IDs on elements.

This gets really like nitpicky, especially when you start working in like frameworks, or if you’re doing something like CSS, bam, bam, block element modifier type stuff, because CSS BAM styling is all about class names. You never use an ID ever. But the thing is, JavaScript loves IDs. Because looking up an ID is super performant because there should only ever be one. So the get element by ID method is very fast by comparison. So if you’ve got something to axon, let’s say a menu, your nav menu, right, you should only have one Nav menu, call it an ID, nav menu.

And then when you need to bind your drop down functionality or whatever to it, use get element by ID don’t use query selector, don’t use query selector all. That’s one of those things. Most people will learn all of those right around the same time. And you might think that oh, well, query selector is super good, because like, I can pass anything to it, including an ID. Right? But it is less performant. And we’re talking milliseconds, you know, you’re probably looking at like, 20 milliseconds versus 39. Yeah, this is all about aggregate, right? If you’re using

it and using it in a listener, or if you’re using it in a function that runs frequently or is triggered frequently, and or it happens on a lot of elements, like that’s going to add up fast. Yes,

absolutely. Because DOM manipulation itself is a fairly expensive task, creating elements, passing them around those, like, creating a simple variable object, you know, with a couple properties, you know, A is true, and B is four and store that, that’s super cheap. That’s it’s so small, but storing an actual Create Element div with all of this stuff in it. That’s an expensive memory task to do.

Could we talk for just a moment about the different ways the different kinds of hooks you can create for doing queries? Because I think this is something that maybe like you and I like are just it’s like second nature to us, because we’ve been doing it so long. But this is definitely feels like something that could be not intuitive to someone newer. Sure. So there’s, there’s IDs, and like they, the robot ID is in this isn’t strictly enforced, like the page will still load. But you can create weird behaviors. But the rule is that on any given page load, an ID attribute should only appear once. Yeah.

And you won’t, you will fail HTML validation if you have two IDs on a page.

So even if you have like an a tag with ID link one, and then you have a p tag somewhere, also called link one. That’s, it’s invalid. It needs to be like, even though there are different kinds of attributes with different kinds of nodes. It’s still invalid, because the ID itself is like imagine like a table. And every entry in the table has to have a unique ID. And then there’s class, which we use for CSS, but you can also query it with JavaScript.

And yeah, so you could do a get elements by class name. Like, let’s say red, right? Like, right, get everything with the class red. And maybe that’s some links, maybe that’s some paragraph tags, whatever.

But then if you use the, what is it? It’s just, it’s just query selector, right? That’s the one that lets you do like a CSS query,

query selector, and query selector all will accept any valid CSS selector.

So you could do a dot read or dot read in those cases, right? Yeah. And then you can also do, you can do query selector looking for data attributes. And I’m actually I, I used this at work recently, I had a form that had a bunch of different kinds of divs on it. And some of them had an attribute called active and some of the had one called inactive. And I created some filter buttons that just grabbed the like, either active or inactive data attributes. And that way, the, there was no like collision with CSS. And but it was still like meaningful data. So there might might be others, those ones I can think of, though,

yeah, no, there, there are a couple others we’ll all throw out there that you can look at which, like one of them is get elements by tag name. So you could just say, get all a tags. You know, again, this is very similar to query selector all but it’s just limiting itself to a very particular part of the the DOM tree that way. And so it won’t crawl through the entire class lists. Because remember, that class list is really big. That’s why query selector and query selector all are really pretty inefficient overall.

And then you can get into all kinds of stuff about like child nodes and Create Element append element append child. So that’s sort of a great thing, though, because here’s what you do, right? If you’re doing a lot of this DOM manipulation, if you’re creating a web app, first and foremost, cache your damn elements. So what that means is don’t run those queries every time you need to do something. If you’re acting on an element all the time, get that element once and store it as a variable. So that you can reference that every time so you’re not rerunning the lookup every single time once it’s that once you’ve stored it,

that’s caching and scripts.

I mean, yeah, it’s I’m using it like that. Think of it like a lowercase c cache. It’s like, okay, you’ve stored it as a variable. As long as that reference stays active, it won’t be garbage collected, so it will stay there and be available to Gotcha. So instead like if I was running query selector all every single time to get all my links? Well, that’s super inefficient, right? We Yeah, we get back that’s a heavy lookup.

But if I’m getting all the links on the page, ver links equals document dot query selector all, you know, a dot link or whatever, or get elements by tag name a, then store that list as links. Now, every time you need it just reference links, because then it won’t rerun that lookup every single time. Right? So it’s, it’s a cached quote, unquote. If I

recall from a previous episode, I think it was the one we talked about CSS specificity. The Id like Id attributes are like the fastest, like, the best. Absolutely. Um, but I think from a practical standpoint, referencing everything by ID specifically makes the code harder to maintain, in my opinion. Because I mean, you have to, you then have to generate a unique ID for each element.

And also, it’s not don’t have to do it for each element, though. Each element that you’d want to Yes, strictly speaking, you only need to do it on the elements, you know, you want to act on. Sure. And if you are doing something that requires a lot, then it makes sense to not do the ID. So a good example, right? If you have a main nav with drop down menus that need particular functionality, it doesn’t make sense to give each one of those an ID and then recall all that,

you know, you want every a tag with a class or something like,

I’m not gonna, I’m not saying never use query selector and never use query selector all, just don’t use them, because you aren’t going to use other things that would be better for the use case. Right? Right. The other thing you can do is go into the Performance tab on dev tools. Now this, if you’ve never used this, this can be very daunting, the Performance tab, because it’s very complex looking. And it’s going to show you this big graph full of colors and stacks and labels of all kinds of things. But what it does is it’ll give you a little donut chart in the lower left corner that will show you layout, time render time, things like that.

And you can start to see like if you pull out the rendering pieces and start hovering over chunks of your code, you’ll start to see where layout shift happens. They’ll be highlighted in in the performance graph. And those are good examples of like looking at how your DOM manipulation is happening. And seeing like, is it all happening? Like in one nice clean block? Or is it happening like smeared across that timeline? Because that will affect things like your web vitals? You maybe have heard us refer to cumulative layout shift before? What is that this, this is a web vital one of Google’s like, you know, PageRank components type things.

And it’s exactly what it sounds like layout shift is when things move around your page. And cumulative layout shift is the amount of that that it does over the lifespan of a page load. And so ideally, you want to try to keep that very limited and consolidated. And you can see that happening in the Performance tab. So if you have a lot of DOM manipulation that happens on page load, this is a good way to see is it scattered and unfocused, or does it all happen in one nice, very clean, boom done type thing, because it measures layout shift as measured frame to frame.

And so doing it all at once, keeps it nice and clean and tight, and it spreads it over fewer frames, whereas if it happens, at 12 different points in the page load, you’ve got way more frames that it’s measuring against. And so that will count more highly against you. Because it’s things moving around a page, it makes the page hard to use this goes back to this. Like they’re trying to abstract UX into a metric. And the notion that things on a page move around think ads, right? Dynamically inserted ads that kind of try to trick you into clicking them by not being there, right. And they pop in to your way talking to hate that it’s that’s the kind of thing they’re trying to prevent. Exactly. So

so this is stuff that if I recall, this was episode 68. Where we talked about page performance. Probably we’re talking about Contentful paint and all that. Yeah,

yeah, okay. Doesn’t feel like that long ago, but maybe it was

it was a 2020 just look it up. Um,

let’s, let’s go to event handlers because this is another area where like, it’s it’s a singular kind of thing that can have a really big impact on the way your code performs.

This would be like onmouseover all that unload. Yeah.

Click is when people use all the time. A couple that people We’ll use frequently are things like on resize, right? Maybe you have some boxes on your page that change their scale based on how big a page is? Or is it? You know, is it landscape or portrait or whatever? The thing is, resize happens a lot. So does mouse move, like mouse move is constantly firing when your guess what moving your mouse? Yeah, these things fire a ton. And so binding JavaScript to those can result in 1000s of function calls in the course of a couple seconds, just constant function calls. Yeah. If you ever if you ever do if you ever want to see it,

make a make a very simple page, like literally just like a word of text, and put a put an event handler there to track the mouse move and snag the x&y coordinates and dump them to the console log, and then just move your mouse around on the page a few times, yeah, and watch your console, it’s pretty great. Wow, it’s a

ton. And so depending on what you’re doing, it’s one of those like, this is one of those areas where we said, like, you can make something that works exactly the way you want it to. But using these kinds of functions needlessly or in the wrong way, can cause that to be very inefficient, especially if there’s a lot of code bound to those functions, you can create a lot of lag, like very visible, you know, perceptive lag in things. If you do that,

I want to say, really, I know, this isn’t in the show notes, but like, so use JavaScript event handlers to replicate default, page behavior. And I’m specifically thinking about this one time, and I forget where it was. But it was, it wasn’t just a random person’s website, it was like a, like a brand new site, and they had all of the links, be void JavaScript links, that when you click on them, it would then change it wouldn’t like do an AJAX call, it would literally change your window location, to wherever the link was supposed to go to.

And don’t just don’t use use this use a regular link tag, you get exactly the same behavior. And I, it just like, blew my mind that this happened. I know that there’s like sometimes like, you know, on submit or something, you want to have validations. And so you need to like capture the onsubmit event, and then run your validations. And then if it passes, then submit it, I get that, that’s fine. But if there is a default behavior in the document, go to that first, and then add the intervening things you need to in like inside of

it, I’ll jump down actually, because your point is a good one for something, I do have an in the notes here, which is passive event listeners. Now, this is not available for every single kind of event listener, but it is specifically available to any event listener dealing with like touch or wheel events. So you know, scroll or touchstart, or some of these, like these interactive behaviors. And what you can do is you can say passive true in the the configuration properties for your event listener. And it basically turns that event listener into a secondary thread. This is not the best way for me to describe this.

But so you know how there’s a thing called prevent default, right? So like, if you are using an a tag, and you’re using it improperly, you know, you’re using it to like act as a button, for instance, to open a modal or something like that, you might have prevent default on it, because you’re going to say, oh, but we’re going to open up a modal with it, or we’re going to cause a behavior to happen. So I don’t want you to actually go to the link, I, I’m going to determine what happens, right? So you would not set passive to true in that situation.

By setting passive to true, what you’re saying is, I promise that we are not going to override the default behavior of this thing, which means it will not block the browser’s default behavior. Okay, so what this means is like if you’ve got an anchor tag that goes halfway down the page, right, and you have an event listener on that link to do something to, you know, to, let’s say it’s just to track the the click, you know, it’s an inpage link, you want to know people it’s like a jump to top that’s a great one, right? Okay, to the top.

You know, those little sometimes if you put a little badge in the corner that like if you’re way down a page, and it just takes you all the way back up an anchor to the top, and you’ve got this little event on it that tracks to see if people are clicking it, but you want it to go to the top of the page. So you say passive trough. And that means the browser sees you click on that, and it says, whatever is happening, when I click on this, I do not have to wait to send the user to the place they have requested to go. Okay, so scroll events, things like that won’t be blocked by the JavaScript thread.

So you get a perceivable increase in speed, because whatever JavaScript you’ve bound to that, it won’t wait on for the purposes of doing the navigation. So that’s something that can help across the board like that helps actual performance and perceived performance. There are two more things you can do with event listeners. One is to target your parents and not your children. So that’s not funny. Don’t laugh at that. That’s not even a joke. That’s literally the words that we use, having

a lot of like, double entendre Oh, today,

we have the nav node, right, like, NAV is a node that exists in HTML, as our a tags, it is more performant. If you want to bind behavior to like a menu and like the links in the menu, it’s more performant to target the nav element that wraps your menu. And then when you fire that loop, just get the target that’s been clicked on, rather than binding it to every single a tag inside of it, you will reduce the number of event handlers in memory from, you know, 10 to one that way.

So you just you have reduced the memory footprint of that by targeting like if you’ve got a list, and you’ve got like, this is an app, and you’ve got some kind of like, maybe you can drag and drop the order of items in the list, you know, instead of binding to every loi, bind it to the UL, and then do e dot target and get the target element that’s been clicked on and then act on it. You right, you only need the one event handler because the parent wraps it. And so it’s gonna capture then whatever activity you’re trying to do,

I forget what I learned that but that was a really neat, like thing where you can assign an event listener to like a, like not at the body level, but like at a specific localized scope. And then it only listens to stuff directly underneath it. That was a real like, real revelation.

The other last item for event handling is to learn about debounce functions. And this is a really simple concept that I think, also can be very confusing. And I’ll try to explain it real simply. So we mentioned for instance, things like the scroll event happen a lot on a page, like when you’re scrolling, it’s constantly firing the scroll event.

And so that can be very, very bad for any event that’s bound to it. But have you seen like, let’s say a site that has like, maybe an animation behind the panel, and when you go to scroll, instead of the page scrolling? it animates something behind whatever’s happening, like maybe on Oh page or something like that, or, or it’ll snap to that very next panel, you know, even though you’ve told a little bit, what is that called?

Because I stopped doing CSS professionally around the time that that was becoming popular. And so I never learned how to do it. What does that call Well,

the ladder things like snap scrolling, that idea of like scroll jacking, you know, for like the purposes of animations and things like that, or infographics is, scroll jacking is the work that I know it by. But what you can do is you can debounce that function so that when somebody scrolls, you aren’t firing your animation events 1000 times. And all a debounce function is is it says, Hey, have you fired this event? Yes, you have, how long has it been? It’s been 800 milliseconds. That’s not long enough. We have to wait at least a second before we try to do this thing again.

And so it, it’s it basically acts as kind of like a buffer to make sure that like if you set that debounce to 1000 milliseconds, one second, that event, the event will still fire but all of the code inside the function won’t fire unless it’s been one second. Okay, so it’s just a way of like, stepping that out. Okay, there is and we’ll have an example of this in the show notes like you can go grab it’s it’s not like it’s just a function you have to include in your JavaScript and then you you’ve big fat arrow it into an event handler.

There is another concept very similar called throttling And I’ll have an example of this to de Belson throttling are very similar, the main difference being that throttling, literally just make sure the event fires on a cadence. So every 500 milliseconds. So no matter what’s happening, it will run that event every half second, maybe it’s capturing the mouse position, you mentioned XY earlier, maybe you get in the xy position of the mouse to like, update the cursor look or something like that. Or to track that maybe your heat mapping something. And so you’re like, Well, you know, I want granular data.

But I don’t need to know the mouse position more than every half second, you can throttle the function. So you’ll get that data every half second, whereas debounce wouldn’t even run if the mouse doesn’t move. So okay, throttling is throttling is very similar to D bouncing, D bouncing will just run less if it’s not being actively engaged. So okay, that’s event handlers. Let me throw two quick ones out here. These are relatively small, and then we’ll hit the last big one. Animations. So you know how you can do CSS animations, right? Wait, what? Yeah, it’s a whole thing. You can do animations in JavaScript, in a very similar fashion, just by changing the styles on an element and putting a duration on it.

Actually, you could do animations in JavaScript before you can do them in CSS. Yes.

Yeah, definitely. Yeah. I mean, that was, you know, jQuery, jQuery UI did a lot of that. But here’s the thing. J. S animations can be awful for performance, especially in the sense of like battery life. Because badly written and badly optimized JavaScript animations will run whether people are looking at them or not, which chews up CPU and on a mobile device will chew up battery or laptop very quickly, if it’s especially a heavy, you know, like a big background animation or some like, especially like something that does a lot of like random gin or things like that.

There is a function, this is where I’m getting into like actual function stuff, there’s a function called Request Animation Frame, that if you use that, instead of something like a set timeout, then when somebody isn’t looking at it, the animation will be stopped on that tab, as long as they are looking at something else. This releases the CPU, there’s an article that will have in the shownotes, it says animations taking place in inactive tabs or stopped meaning if a user navigates away from your tab, and you have an animation that releases the stranglehold it has on the CPU, because of the better performance, battery life and paid responsiveness are better on low end devices and mobile browsers.

This is all about just how the browser in queues that animation and triggers it. It just makes it smarter, and therefore more performant. So cool, it’s yeah, it’s just like a little, little known function that is used for helping that along, rather than just writing your thing, because what a lot of people will do is to measure whether or not to run an animation, they’ll include a set timeout. And so if the animation hasn’t completed yet, then it’ll wait. But those set timeouts very much like event handlers, go into memory and sit there and sit there and sit there. Whereas request animation frame is very intelligent about knowing whether or not something is still going or not.

So very useful. The other one is called performance marks. There’s it’s literally performance dot mark, performance measure, these are built into JavaScript, they are really great for measuring how long something takes. So if you’ve got a big function that you think may be slowing things down, you can throw a performance mark in it, and spit that out to console. And it will give you the start time, the end time, the execution time. So you can figure out did it take 712 milliseconds to run or 14 milliseconds to run. Or this is really useful for things that have loops.

Do While for each, you know, map functions, all of this, especially if you have nested loops, which you should always try to avoid nested loops get very nested loops. And for anybody who’s done like algorithmic stuff, computer science stuff, nested loops, increase performance impacts exponentially as you add them in. So like that’s something you want to avoid that at all costs. You want to add these performance marks that will give you a good idea of how well those loops are running. Because loops are an area where you can get very heavy and do things like maybe you say, oh, you know what?

We’re looking for one thing once we find that there’s no reason to keep looping, and throw a break in there and then break out of that loop at the earliest. just convenience. But those performance marks are just a really handy way to get information on how heavy your JavaScript is and how, how performant it is. Other thing you can do with it. And this gets super cool if you’re a nerd like me is, if you’re using something like Cypress to run tests on your code, you can add performance as a requirement for your test. And if that performance measure spits out over 300 mil, or what’s, what’s the dirty threshold? 400 milliseconds, right?

Whatever the dirty threshold is, the dirty threshold is like the, how fast does something have to be, so that it seems imperceptible to the user? Like it, it feels instant? Maybe you store that in your test, and you include those performance measures. So that when your Cypress test runs, it’s above the Doherty threshold, it’ll fail your test? Like, that’s cool. Yeah, like you can actually make this part of your process. So it’s not something you do manually, it’s not something you have to just remember, build it in that way. It’s kind of a neat, you know, high, you know, high level way of approaching these kind of problems.

We talked about using Cypress for testing in Episode 91. Yeah, with Jessica. Jason. Exactly.

Yeah. Okay, the last one, this is slightly bigger, but I thought it was a good one to end on. We’ve referenced it a couple times. And this is a little more high end. But it’s a good like thing to like, get your brain kind of going and go learn something is memory management, right? There are really two places where JavaScript hurts performance, that CPU usage. And that’s memory management. Okay. I mean, those are the two functions of computing, right is how much does it pull your system down? And how much space does it take to do that? You have a tool in Dev Tools, called allocation sampling.

If you open up your dev tools and go to that memory panel, you can turn on allocation sampling as the page loads, and record the memory usage over the course of that page. Okay, this is super handy for going in and seeing like, which functions are using up the most memory. So this kind of comes back to like, if you want to use those performance marks that I was talking about, you could target those functions that appear to be biggest with that, and see, why are they big, because keep in mind, just because it’s big doesn’t mean it’s bad.

If it’s doing what it is supposed to do in the most efficient way, maybe it’s just a big task, like that’s right, it happens, you know, it’s an application, yeah, it’s gonna be that way. But it could be a signal that you need to go in there and look at how you’re handling that. JavaScript comes with built in garbage collection, when it sees things get dereferenced, it will try to clear them out of memory. But sometimes, depending on how you’re scoping variables, or if you’re not cleaning up after yourself, those things will stay in memory and just be there. These are where those memory kind of leaks happen.

And I we said at the start write badly optimized JavaScript code creates opportunities for attacks, or failure for bugs, all of this. So knowing where things are getting stuck in memory and not garbage collected, because the system things are still in use can be very, very useful. There is an article on how to fix performance problems using dev tools. It’ll be in the show notes that talks explicitly about allocation sampling. Again, this is this isn’t the most complex thing, the that performance reports pretty complex looking, allocation samplings, very straightforward. It’s just a list of all the function calls and how big they are.

I think it’s still cool that like, it’s kind of full circle. Like we’re, we’re back to being being concerned with, like memory allocation and stuff.

The other part of memory management is a feature called heap snap snapshots. Now, especially if you’ve done Java work, but I’m sure I don’t know. Is there something similar to this in Ruby? Aaron, like, is the heap something that comes up? Is that what do you mean? Does that a lexical reference that blank uses?

Possibly like, what what do you mean? So heap generally

refers to the pile of stuff, that heap of stuff in memory, right? Like all the references all, you know what’s going on? Java is very concerned with like memory usage. So like you’ll you will get heap snapshots of threads to see what everything is doing. If you’re debugging, like Java code, things like that. You can do a heap snapshot of all of the threads in the browser in a window in the memory area. Keeps snapshots are very Much like allocation sampling, except they are literal snapshots, they are a picture of a moment in time. You can do multiple heap snapshots. So you can do it, save it, reload the page, do it again.

And, like over time, okay, this is cool, because A, it lets you do comparisons. You can compare one heap snapshot to another to see how things change. Or if you make a change to your code, and you want to see how did that change the memory footprint of a certain function, take a heap snapshot, update the JavaScript, rerun the page, take another heap snapshot, compare them. Super useful. The other thing is, it gives you four different metrics, constructors, distance, shallow size, and retain size. And these are a little complicated, but constructor is just the function. Like that’s what made the call.

And a lot of those will be browser things like there’ll be things not in your code as well. So you have to kind of look through them to find like your particular calls. distance is the distance from route, which is like how far down the JavaScript stack it is. So like, how nested does it how far into your code is it if it’s deeper, it takes longer to run because it’s, you know, it takes longer for it to process that entire that entire stack. Shallow size is just how big that memory object is. And then retain size is how much memory will be freed by deleting.

And again, this entirely depends on your code, you can’t always delete every reference. But if you do have references that you don’t need anymore, and you’re trying to optimize that code, targeting things that have a high retain the size, could be very useful. So that’s my list of suggestions. Oh, it’s a lot. And like I say, this was a lot of like, technique stuff. And,

you know, is it is it, you know,

grabbing pennies to save nickels are what what’s the phrase a saving nickels to move $1 It’s some kind of duck. Yes, we’re talking about incremental improvements in a lot of ways. But these are the things especially if you want to get into big app development, big JavaScript stack development. Over time, it really adds up. It’s just like, minifying a file. Yeah, a minified file is a little bit smaller. But over the course of all of your JavaScript, you’re gonna reduce that file size 20 to 40%.

But I think even just as professionally, if you’re doing this as a job, like it’s a craft Yeah, like, there there is, artists and artistry behind like writing good code, and you should care that you’re not being wasteful or like using a lot of extra cruft when you don’t need to

be and it shows in the end product at the end of the day, like you know, a good metaphor Have you ever like been on YouTube or Tik Tok or something like that and seen like,

APE that sort of videos Yes. Very much video internet.

Have you ever seen somebody who is a professional drywall finisher?

Oh, I’ve seen seen professional like contractors and things including drywall including grout laying. It is so sad like to watch them work

what and I consider myself very good at drywall finishing my dad was a construction guy, I’ve I have done more mudding on walls and I could even count I’m good, I can produce a good finished piece of work. I’m a little slow at it. And my technique needs a lot of work.

And you watch some of these guys like they make their living doing it and it is nuts because a they’re they’re wicked fast. But the quality of their work in that amount of time is also so high and it’s like they could do it just like me they’re paid by the hour they could go slow and and get that but right there is a quality of craftsmanship there that really is apparent when you have honed those different techniques and this is just like that the walls still ends up painted in the end you still walk into the room and it feels the same in a lot of ways.

But that but they the the way they do it though like a really good drywall or the when they put the the mud on. A lot of times it looks like they don’t have to do any sanding at all. Yeah, like there’s just mud on the screw head or the nail head. And it’s like, awesome. It’s actually it was watching. I saw a video this morning of someone applying grout to a bathroom floor and there was no grout to be cleaned up. It was only going into the cracks and it was like a perfect little like white finish and Oh it’s beautiful. Yeah,

yeah, it makes makes me love mint. Owl slow and crappy. But I hope this has been educational and helpful and has given you some thoughts about how you approach your JavaScript. We’re gonna take one Quick break, and be right back. I think one thing I want to know about is, whatever it is you all do for performance, or you know what tips tricks you have. So be sure to let us know about that. Because, you know, the end of the day, this is a deep well, like this is something I think we could easily do another two or three episodes on, or get into real specifics. For instance, we mentioned loops, right?

There are a lot of ways to write a loop in JavaScript or loop or loop for each maps, like there’s so many ways to go through and write those loops, which ones are better than others. And when you know, that this notion of we were saying like, well, query selector all is super inefficient. Well, how inefficient? Is it? Those are numbers we can know. And we can actually quantify. So I think we will probably revisit this topic and get into maybe some more nitty gritty about it, now that we’ve kind of laid the foundation for some of these concepts. But absolutely, let us know.

I’d be interested to know about, like, either within coding, like in what ways do you see like your work as, like an art, or artistry. And if not coding, like if you’re, they’re newer to coding, or that’s just not an important thing to you? What are the things that you care about to the level of artistry or like, artists and ship? I think that like, if you really care about doing something like you want to do it the best you can, and you want to learn these nuances and things that is kind of like requires extra effort to learn. And I always love hearing stories about the kind of stuff that people really get into, it’s really fascinating to see when you see

like, just not just JavaScript, PHP, Ruby, whatever, like when you see like, really well written code, like, Oh, it’s

beautiful. Yeah, there’s

something about like, seeing like, some really incredible use of conventions and shorthand and all of that, like, that’s well formatted and structured like, you know it when you see it, and there is something very satisfying about that.

It’s funny, it does exactly what’s supposed to do nothing more, nothing less. And it’s sometimes it’s even, it seems like maybe, like it should be less efficient, like you should change it, like, oh, well, why aren’t these in this method instead? And then do the way you look at it? Like, oh, no, actually, no, I understand why they did it this way. This, this is correct. 100%, you know, like, hot marks on on this code. But anyways, come in. Tell us about that. Tell us about your JavaScript stuff. Tell us about your artistry.

You can share with us on Twitter, or facebook.com/truckin, UX, or trucking ux.com/discord. And you can see occasional memes that we post about these sorts of things, instagram.com/truck and UX podcast. And last but not least, come help us make transcripts, you can support us for just a couple bucks a month, that would be fine. At trek, new x.com/support, which will redirect through to our Patreon.

And I think you know, there’s something else really important to remember about all of this is, you know, while this episode was very JavaScript focused, and and we really tried to bounce around between development and design, and UX, and accessibility, and all of these different things. Even though this was very developer centric, good, efficient code is about UX. Because making sure your interface is fast, making sure that things behave the way they’re supposed to do, making sure that your site doesn’t interfere with other sites that people have open.

You know, you’ve we’ve all been there where like one tab starts to crash on us. And it pulls your whole browser down, you know, like, these little things matter. And even though you are a developer writing code, you can directly impact the experience a user is having on your site like that is a power you have that as a superpower that is ingrained in you. And so, spinning this time isn’t necessarily just about oh, making clean code or or making fast code, because you are interfacing with that human being and you are having an impact on the way they use your site.

So by focusing on this stuff, by finding these tweaks, and these little like dials, you can turn to make your file a little smaller, make your function a little faster. It’s all keeping your personas close and your users closer. Bye bye

Exit mobile version