April 20th, 2020 × #webdev#javascript#performance
Hasty Treat - 5 More Things That Make Your Site Slow
In this episode Wes and Scott discuss 5 more performance tips to make your web applications faster, including bundling JavaScript code, enabling gzip compression, loading scripts asynchronously, and adding database indexes.
Transcript
Announcer
Monday. Monday. Monday.
Announcer
Open wide dev fans. Get ready to stuff your face with JavaScript, CSS, Node modules, barbecue tips, get workflows, breakdancing, soft skill, web development, the hastiest, the craziest, the tastiest web development treats coming in hot. Here is Wes, Barracuda, Bos, and Scott, El Toroloco, Tolinski.
Scott Tolinski
Welcome to syntax. In this episode of syntax, we're gonna be talking about 5 more things you should know about performance to make your applications much faster very much faster. We got so many things, so many tips, so many little things that you can do here. So this is part 2 of a series that who knows how many parts Yarn gonna be because there's just a lot of perf tips. We have an endless stream of them here. My name is Scott Tolinski.
Scott Tolinski
I am a full stack developer from Denver, Colorado, and with me, as always, is Wes Bos.
Wes Bos
Hey, everybody.
Scott Tolinski
Wes Bos, coming ahead to you from the BossHaus.
Wes Bos
Bos.
Wes Bos
I've been asking people what to I'm building a little shed office. I'm trying to figure out what to call it.
Scott Tolinski
Bos was my submission.
Wes Bos
BossHoss.
Wes Bos
Some Node people accept to call it the bike shed, which I love for sure. The bike shed's fantastic. Yeah. Right. That is very good.
Scott Tolinski
And that that's where Wes home base is gonna be, Will. He ships some Node. And while he's shipping code, he's gonna wanna make sure that there are no bugs in that code even if he is working out of a shed. We don't want bugs. No bugs in the shed.
Scott Tolinski
I actually had a dream last night with a bunch of creepy crawlies, and I'm not into bugs right now. So if I wanna keep track Awful. Yeah. I wanna keep track of my bugs, I'm gonna do so with Sentry. It's actually funny. My dream involved a a brown recluse spider, and we were, like, sleeping in somebody's basement in sleeping bags. And we lost the like, oh, there's a brown recluse spider. We gotta take care of that. And then we couldn't take care of it, and we Wes lost it. And then we're in sleeping bags. Best place you wanna be with the brown recluse spider on the loose is in a sleeping bag. So you're gonna keep track of your bugs, and you're gonna do that with Sanity at century. Io. Now it is the perfect error tracking solution because it gives you all of the information you need to know while keeping track of your bugs. What release it happened in? Well, if you have a a source map set up, it can show you exact line where this bug happened, what browser, what user committed this error, all within an amazing fantastic interface to keep track of all of your exceptions.
Scott Tolinski
You can mark them as complete, finished, whatever, and, again, attach them to GitHub issues. It's so good. I it's an essential service for my business, and I know it will be for you. So head on over to century.io.
Scott Tolinski
Use the coupon code tasty treat, all lower case, all one word, and you're gonna get 2 months for free. Yeah. That's a lot of that's a lot of free. So check it out, century. Io. Alright.
Scott Tolinski
Perf tips. Five more performance tips. Wes, do you wanna hit up the first one?
Wes Bos
Yes. The first tip we have here is shipping too much JavaScript.
Shipping too much JavaScript
Wes Bos
This is something that happens. I think this happens because a lot of applications, especially ones that have been around for more than, I don't know, more than 5 years or so, They're built on the fact that your JavaScript depends on other JavaScript and that depends on other JavaScript, and it's very brittle. You can't just take part of the JavaScript out and expect everything to work because they haven't been written properly with modules or things like that. And it's all sort of just jammed into the the global space, and it's pretty common. Like, I I look at a lot of, like, online stores and things like that, and you can tell that they are shipping tons of JavaScript because it's just way too complex to figure out how do I only load part of it or how do I load it on the pages that it is needed. So, thankfully, that has gotten a lot easier with tools like Parcel or Webpack and React lazy loading code as you need. Webpack has a bundle analyzer that will tell you if there's unused Node. Code what's it called? Tree code shaking. Tree shaking is when it will figure out if if if parts of the library are unused, and it will drop those from the final build. So there's really a lot you can do in terms of slimming up your JavaScript.
Wes Bos
And the tools that we have right now for being able to look at what is large and and what is what can be code split make that a lot easier these days.
Scott Tolinski
Yeah. It does. And that's really the key takeaway from this one is that, yes, you have some responsibility here. You can't load up Bootstrap and Material UI in 1 project and have your bundle stay small. Right? You have to to to keep be cognizant of what you're adding to your project at all times. And it's we're we're so lucky that we do have these tools for us, right, now that we can have a bundle analyzer. I know Meteor has a bundle bundle analyzer as well. Anything you can do to visually see your application, I bet Parcel might as well. We should check into that. But either way, these kind of tools are extremely, extremely helpful to find out where the bloat is coming from. You might not even realize that Node particular module you're adding might have another module that it uses, which has another module, which all of a sudden you look at this thing and say, holy cow. I did not know that this React toggle was taking up Yeah. You know, 200 kilobytes of of JavaScript to them. Or, like, a package was
Wes Bos
meant to be used server side, but you just included a client side. I've done that with a Yeah. A slug library.
Wes Bos
The slug library included a description of every Unicode character ever. So, like, like a Unicode heart, it means hearts.
Wes Bos
A crying emoji means laughing and crying. And, like, surprisingly, if you ship a description of every single emoji to your browser, that will add I think it was, like, 2 megs or something like that. It was huge, and I was like, what is causing this? Yeah. It's just silly things like that where you, Npm, install something, think it's gonna be fine. You like Scott said, you have no idea what that is requiring
Scott Tolinski
under the hood until you use some of these tools. Yeah. And I I like, we and we've talked about these bundle end delays just a couple of times now, but, like, you definitely should get some sort of a visual on it. Like, what is because it it's so powerful when you see these giant pizza pie slices taking up a big chunk. I am, like, almost obsessively eliminating some of that stuff. Like, how can I get this smaller? How can I get this smaller? Okay. Next 1 is going to be not bundling your code, which is a big problem that you probably don't want to have. And this is a problem that's becoming less and less prominent JS bundlers and webpack and parcel and all these things become way more commonplace.
Not bundling your code
Scott Tolinski
But for a very, very long time, and still in a lot of places, it was sort of weird to have a a build system. I remember the first time we instituted a gulp process in our workflows, and a lot of developers had a really hard time getting up and running with it because it was so foreign and different than what they were used to doing. And same with Grunt and Wes any of these things came out, at first, it was like, oh, I have to run this thing every time I save a file Node. I mean, it was just definitely like a process, and maybe CSS preprocessors were the lead into that. But bundling your code together is an essential thing about, releasing something because what it does is it it takes all of your your things that you needed to do. It minifies them. What it does is it removes the the white space. It makes the the characters less redundant, and it it just gets your project ready to go so that you're serving 1 file, 1 main file, or maybe potentially, lazy loading some files, but you're serving 1 main file rather than 1 giant giant file or several
Wes Bos
giant files. Right? Yeah. Because at the end of the day, we talked about this in the last episode JS that, more requests cause that Waterflow water, sorry, waterfall Wes. There's only so many I forget what the thing is, but there's only so many requests that your browser could make at one time.
Wes Bos
And then once you get past that, it'll start to waterfall them for you. So bundle it up, and then sort of goes with bundling is compress them. So what's the one that we use in in JavaScript land? Is it is it Uglify? I don't even know what they are under the hood anymore. There was a Babel one. There's,
Scott Tolinski
even some new ones that are coming out that are I don't wanna say that they're, like, brand brand new or something, but they're, like, things that are much better developed by Google. I'm totally blanking on the names of them right now. In fact, the new React router uses it, and it like, they got a ton of performance.
Scott Tolinski
React router 6 oh, so, React router six is using the new well, not the new, but it's using the Google Closure Compiler.
Scott Tolinski
I don't know if you've heard of this compiler, but it's really super, really super good. And it got their bundle size from 28 k, that that's minified, to 88.5 k minified. And that's only 2.9 k g zipped as opposed to 9.4 gzipped. So, wow, big savings there.
Wes Bos
Yeah. I I remember this from a long time ago. Yeah.
Wes Bos
And and everyone said, like, it's good, but, like, you have to write your code in a certain way in order for it to work.
Wes Bos
It's a Java application, which is really funny.
Scott Tolinski
Yeah.
Wes Bos
Closure Compiler is a Java application for minifying JavaScript, which is pretty interesting. So I I don't know what they're doing under the hood, but it I guess there's huge benefits if you write your application in a certain way that it can then be minified.
Gzipping
Wes Bos
What else we have here? Gzipping. So generally, g g zipping is something you just turn on in your server.
Wes Bos
And then when your server serves up a JavaScript file, it will do things like if you have a variable called Scott 47 times in your JavaScript, it will realize that I'm not gonna send the word Scott 47 times. I'm gonna send this the word Scott once, and then I'm gonna all those other spots, I'm just gonna point to the original Scott.
Wes Bos
And then that will that that's what g zipping is. It makes it makes redundant words and letters and characters, only be sent once over the wire, and browsers are able to unpack that. So it's not like, gzipping is not something you have to turn on in your browser.
Wes Bos
It's something you turn on to your server, and then your browser will Node how to unpack gZipped code. So that's generally turned on by default, but it's certainly worth checking because it's a easy win for all servers.
Scott Tolinski
It's an easy win. Do you remember there used to be, like, a PHP module? What was that called? The Google one that you just added, and all of a sudden, your site got a whole bunch of compression benefits from it. I I am totally blanking it. It was like Google page speed or something, but it was like some module mod that you could add on to PHP. And I remember the 1st time we did it in a Drupal site. We were just, like, blown away. It was in the NGINX that we did it. But, there Oh, yeah. Yeah. It's an Apache and NGINX module called it's called Google PageSpeed. Google PageSpeed. Yeah. Stuff like that is just endlessly important when serving your Node, and often Wes don't think about it. But if you do have control over your own server, it's one of those things that you do wanna make sure that you are utilizing to its full capacity.
Loading JavaScript asynchronously
Scott Tolinski
Next one is going to be loading JavaScript synchronously.
Scott Tolinski
I always I always wanna say, like, synchronicity.
Scott Tolinski
Synchronously.
Wes Bos
So this is basically Oh, sorry. That's supposed to be asynchronously.
Scott Tolinski
Yeah. I was, like, trying to figure this out. I was like, why would that yeah. I was as I was reading this, I was like, wait a second.
Scott Tolinski
So this is often you'll often see this in on libraries when they tell you to like, here, copy and paste the script at the bottom of your Node. And it'll be a little property in the script tag that says async or I'll say differ.
Scott Tolinski
One of those things that's async this attribute means that it's executed as soon as it's downloaded without blocking. Right? So blocking is when something loads, everything else waits for it. Right? What this async means is that, hey. The rest of this stuff can Node.
Scott Tolinski
Right? But this thing's gonna download just sort of on its own. Now the defer tag, it also does not block. Right? So it's not going to sit.
Scott Tolinski
It's not going to block any of your loading. But unlike async, defer is only executed after the entire document has finished loaded. So if your package, like, isn't needed right now Node now, you can always defer it and, at least use async
Wes Bos
here. Yeah. I found this really nice, Stack Overflow that explains what happens because back in the day, we used to just put all of our script tags in the head of our doc. Yeah. Right. And the JS the reason we did that is because we wanted to make sure that the JavaScript was on the page first and then the HTML, and then we moved to putting the script tag at, like, before the closing body tag, and what that did is it made sure that the tags were on the page before the JavaScript.
Wes Bos
So this, like, was really cool because it tells you how the browser works. So when you fetch the page, like a index HTML, then the browser goes and starts parsing the HTML. So it downloads all of the text, and then it says, alright. I'm gonna turn this text into HTML elements, and that's that's the parsing step.
Wes Bos
But when the parser runs into a script tag referencing an external JavaScript file, so script source equals bundle dot j s, the browser goes off and requests that script file. Meanwhile, the parser blocks and stops parsing the other HTML elements on the page. So, if you have, like, an h one tag and a paragraph tag that says thanks for visiting my website, that will not show up until the JavaScript in the head has been totally downloaded.
Wes Bos
So that's number 5. After some of after some time, the script downloaded and subs is subsequently executed, so it runs all of the JavaScript in that file as well.
Wes Bos
And then finally, the parser continues with the rest of And that that's why we always told you, put the script tags near the closing body tag because you at least should show your user something on the page while you're downloading this JavaScript because likely, they're not gonna click the buy button and the second the page loads, and that just gives a a faster perceived value.
Wes Bos
But now with the async and defer tags that Scott was talking about, it doesn't matter where you put your script tags as long as you know that you're using those properly.
Wes Bos
In my tutorials, I still put them right before the closing body tag because it's a bit of a foot gun if you don't a 100% understand how they are on the page. And then also putting them near the closing body tag JS you never have to deal with waiting for the document to be Node, and, like, that's in jQuery days, we would pop everything in dollar Right. Dollar sign,
Scott Tolinski
whatever. The way for the brow yeah. Yeah. Documentary.
Wes Bos
Doing all of that. My gosh. Yeah. You don't you don't need that if your code is loaded after the HTML elements because you know that it's on the page already because it came before.
Scott Tolinski
It's funny how many problems, like, React solves here. Like, I don't think about this stuff at all. Yeah. You don't have to think about any of that. It's amazing.
Scott Tolinski
I have a, a hook that I use to load scripts that I wrote. It's like a script loader. Yep. And it it's like, is the script loaded or not? It just spits out a bully, and you pass in the script or whatever. And then you only load external scripts when you need them. Like, I don't load the the checkout stuff unless somebody clicks on the checkout.
Scott Tolinski
So, yeah, it's so funny how many of these problems are taken care of. You just don't have to worry about them as much.
Wes Bos
That's, like, ideal world for me is that, like, most developers shouldn't have to know how this stuff works because they're either not gonna care, they're not gonna have enough time to actually implement it, or They got other stuff to worry about. Yeah. They got other stuff to worry about. So, like, just let the let the tools and the frameworks do that heavy lifting for you. It's the same thing with Gatsby and image compression.
Wes Bos
Let something else do it for you because it's too hard for most most of us. Yeah. Yeah. I'm into
Scott Tolinski
that. Alright.
Scott Tolinski
Last 1 is going to be this is going to be a DB side of things. And sometimes, when you're working with a database and you are not a database person, you might neglect certain things. And one of the things that gets neglected often is defining indexes on your database.
Defining database indexes
Scott Tolinski
Now it's different for every single platform depending on how you do it. In Mongo, it's just like a one liner. You're saying, hey. This field is an index. Now what is an index? Well, an index JS, basically, you could think of it as sort of like a so table of contents JS basically an easy way to look up things that are commonly used.
Scott Tolinski
So if you have an ID field or maybe let's say here's a better example because an ID is almost always automatically indexed. But let's talk about, like, a a slug.
Scott Tolinski
Right? A slug is something you'll often look up a page by. Right? The slug comes in. You send that slug onto your server.
Scott Tolinski
That slug then is in your, database query.
Scott Tolinski
And what you need to do is make sure that you have an index on that slug because what it's going to do is it's going to build what's called an index, and it makes the lookup infinitely faster.
Scott Tolinski
So it's definitely something that's highly required anytime you're doing any sort of lookups JS you wanna make sure that you have your indexes on your DB fields. Now a lot of platforms, like I said, take care of this different in different ways. Some do a little bit more automagically than others. But with Mongo, it's it's just typically a one liner. Just look it up. How do I place an index? You're gonna wanna have an index on anything you do a find on, anything you do a sort on, anything you do a a filter on or an ordering on, any of that any of those fields.
Wes Bos
Yeah. I I always do it immediately on slugs, emails, IDs it comes with, and then any other, like anything where you're comparing values, greater than, less than, dates, things like that, that will make sure that those things are nice and fast. I also my Mlab, which is my database hosts, which is now MongoDB Atlas, they all they send you an email, I think weekly, and tell you what you should pay indexes on because it says like, hey. You ran this query a 100 times last week, and it took on average this long. Throw an index on it. You can't index everything because then you run out of space because the way that it works is that it put I think it puts them in memory. Yeah. I think it puts them in memory. Where it puts them, but somewhere. Basically, every time you put an index on something, it has to loop over all of your data and store that info. So, like, if you have a very large database, that certainly could take hours, if not days, to build indexes for your existing data. But in ESLint most cases, at least in my data, it's very small. Only, I don't know, 4 or 500,000, entries in certain tables. It's it's not it's pretty quick to do something like that.
Scott Tolinski
I absolutely love the Atlas side of things where it, like, tells you what indexes warp do have you used the Compass app that they give you with that? Yeah. Yeah. We use it in,
Wes Bos
I think 3 of my courses Wes use. Yeah. On Good DB Compass. Compass is great, and it tells you where you Node indexes,
Scott Tolinski
lets you know all that stuff. So you need indexes in your database. I wish I knew more about them within other databases.
Scott Tolinski
Like, I don't really know what the index situation is on other databases. I just know that it's a thing you need. It's funny that, I think a question everybody asks when it comes to indexes, it's just sort of like, well, if the if the black box is is, you know, so solid, why don't they make the whole plane out of the black box? You know? That that whole joke is like, oh, the indexes Wes why don't you just index the whole thing? And it's funny. I'm so glad you touched on that because it is. It's the question that everybody asks, like, the moment they learn about indexes.
Wes Bos
Yeah. Joe, this thing makes it faster? Slap that on everything. You're right. Yeah.
Wes Bos
That's 5. That's it. Alright. We'll stop there. No more. No more perf tips for you today. Thank you so much for tuning in.
Wes Bos
We've got some more coming up, so get ready.
Scott Tolinski
Get ready. Strap yourself in and get ready. We got 5 more coming at you some other time in the future.
Wes Bos
Beautiful. Alright. Thanks, everyone. Catch you on Wednesday. Peace.
Wes Bos
Peace.
Scott Tolinski
Head on over to syntax.fm for a full archive of all of our shows, and don't forget to subscribe in your podcast player or drop a review if you like this show.