This course has been updated! We now recommend you take the Intermediate React, v5 course.
Transcript from the "Code Splitting" Lesson
[00:00:00]
>> Let's move on to code splitting. So what I want you to do right now is we're gonna start from with our project all over again. So we're not gonna build on top of the tailwind CSS, and we're gonna rebuild from that last version of the repo that we had.
[00:00:16] So the way I was doing that as here, let me make this much bigger I'm gonna copy. Let's see, we'll move intermediate. We need to be in desktop. And we're gonna move intermediate to tailwind, so I can ignore it. And then I'm gonna copy from 12- portals and refs I need to move that from this.
[00:00:52] So we have this complete intro to react project. I'm going to copy from that project/12-portals-and-refs and I'm going to move that to we're going to do code-splitting next. And then I'm gonna code in code splitting There we go. So again, this is just a fresh copy of the repo, you can see here we don't have any tailwind stuff in here.
[00:01:24] And we are going to be writing code splitting. All right, so let's talk about code splitting, what it is, why we want to do it why it's important. If you have a large application, a really big one like a Netflix sized one, like a LinkedIn sized one, were it's several megabytes of JavaScript.
[00:01:51] Sometimes it's unavoidable that you just have big libraries or you're doing a really big heavy lifting thing. I can't imagine you can fit things like Adobe Photoshop, which they're doing in the browser. Now, you can't fit that in under a couple of megabytes of JavaScript. It's a very big application.
[00:02:07] So you have two choices there. You can make your users wait forever for it to load, right ,or you can be intelligent about what code you send to them first. Send them the most important things like the app shell, welcome screen ,hello screen, tooltips, and then don't panic and load everything in the background.
[00:02:25] Right? That's the way to do it is panic, right? Just kidding. But the way to do it is something called code splitting, right? We send them the most important things first so that the browser can start loading everything that it needs to start loading. And then in the background, we can start sending them.
[00:02:43] Things that they need to kind of finish that out. And or we don't have to send them the parts that they don't need yet, right? So for example, if I'm on linkedin.com, and I'm just scrolling through my feed, I don't need all the JavaScript for LinkedIn recruiter right?
[00:02:57] So I can just not load that until the user heads there or expresses intent to go there. Or if I'm not signed up for LinkedIn recruiter downloaded it all right. So you do this through a process called code splitting. I'm gonna show you kind of the base way of doing it, I'm gonna show you how to do it, how to code split over routes, which is not always the best way to do it, it's kinda the obvious way to do it, but you can also do things like.
[00:03:26] I'll show you how to code spit out the modal, which is a terrible idea because it's such a tiny amount of JavaScript. But I'm gonna show you how to do it anyway. So the thing I'm gonna say about code splitting is it's, easy to make code splitting a negative thing in your application as well.
[00:03:42] For example, if we code split out our modal, it's just adding latency to something that didn't need to have latency added anyway. You need to be splitting out actually a couple hundred a kilo. Well, let's say at least a hundred kilobytes before it makes any sense, right? Otherwise you're just slowing down the user for no good reason.
[00:04:02] And you're complicating your app for no good reason. All right, so we'll get there, let's talk about it. Add it in like React complete intro to react version five. So that would have been intermediate react view one. We used to use the thing called react loadable. You don't have to do that anymore.
[00:04:21] You can actually just do it directly with react with something called react.lazy. [INAUDIBLE] Okay so let's head to app.js, And up here where we're importing all this stuff from react we have to import two more things, one's called lazy. And one is called Suspense. Capital S in Suspense, lowercase l for lazy.
[00:04:50] And we're going to code split out apps. Are our routes rather so that we don't load details and we don't load search params upfront, we only do it after the user requests it. So the first thing is delete line five and line six. The import details are not the same context.
[00:05:09] You want to delete details and search prompts a line to add lines. Five if you deleted theme context, put that back in. So delete search params and delete details. Okay. Then I want you to say const details= lazy. And then we're gonna write In a function that calls import, this is called dynamic import.
[00:05:43] And it's from ./details. Okay, and then we'll do the same thing for search params=lazy. And then we're going to import from ./search params. Now what have I done here. Let's talk about import first. This is something that's built into JavaScript this is actually part of the ESM six modules spec.
[00:06:17] These are static imports, which means that these cannot change. So, for example, you cannot say like constant x equals./ Theme context.and say import theme context from, X. This line does not work because this is static. This thing will only work If this is actually a fully supplied string at the time, in other words, this does not execute at runtime this executes like build time, your tools are meant to pick this up and therefore, you cannot do dynamic imports this way.
[00:07:01] This is a departure from how common JS worked, right? You used to be able to say const or theme context equals require x. This used to work, right? Because this was done at runtime, this was dynamic. So they provided this thing called Import like this to kind of bridge that gap.
[00:07:25] So what this does, is it actually gives you back a promise and that promise when it resolves is that module. Again, this is not a react thing. This is just a JavaScript thing. Okay, so that's what import is it's dynamic import. So in theory, you could say constx = blah.
[00:07:48] But it's not gonna work. We're gonna say, JavaScript will let you do that, Parcel won't let you do that. Because Parcel is gonna say, hey, I see a dynamic import here, this is somewhere I can split the code, right? I don't have to set up parcels or do anything, it just figures out like I see dynamic import, I'm going to split out the details module.
[00:08:08] Did not include anything in it. And I'm only going to load that when it's asked for. Okay? Lazy is gonna make a component out of this. So this is now a component that we can render like we do here. So we actually don't have to change any of the code down here.
[00:08:25] This is all just gonna work out of the box. Likes but that's what lazy generates. You can see here that lazy returns to you, a lazy exotic component I did not know that's what it's called. But now I want to use it everywhere. [LAUGH] Cool. We're not quite done yet.
[00:08:44] What happens when we try and load the Detail page and it's not loaded yet. Well, right now react doesn't know what to do. I actually don't even know what to do. I think it, would it crash, does it crash? It doesn't load because you'd have to start the server, okay.
[00:09:06] And today I need to NPM install again. Cuz I didn't do that yet. Yeah, again, notice we don't have to install anything to make code splitting work. It's all built into React and built into Parcel. All that stuff just works out of the box. No additional dependencies required.
[00:09:33] Yeah, like I thought it just doesn't know what to do in a crashes. So we have to tell it what to do when it loads this and it doesn't have what it needs. That is what suspense is for. Suspense is basically this component that you can throw in there.
[00:09:46] It says, hey if you hit me or you render me and something is still loading inside of me, do this until the thing finishes loading. So here inside of strict mode or inside of theme context or inside a browser, it doesn't really matter. Wherever you wanna put it.
[00:10:02] We're gonna put it here. We're gonna put suspense and we're gonna say, the fallback, is equal to whatever you wanna put when it's loading. So I'm gonna put like an h2 here, that says loading or something like that. Or be patient, you weirdo, I find it best like user experience to insult your users on a regular basis.
[00:10:30] Let him know who's boss. I'm a good developer. That's what my wife tells me. All right, so inside a strict mode here. There we go. And now we have this suspense thing. So if you refresh the page for a second, you'll It's goes fast enough, but you can probably kind of sometimes see it up there.
[00:10:53] Loading, be patient, you weirdo, right? Obviously, it's low loading for your local development environment. So it's extremely fast but that's the point. Obviously, what you should do here you should make some sort of like nice loading experience. Don't do it like this, right? And you probably want to load the homepage every single time and not make the homepage lazy loaded.
[00:11:15] You have to ask yourself, like, how does my app work? And how do I expect my users to navigate around? I'm just showing you how to lazy load a route. It's up to you how you want to apply that. But to prove my point here, let's refresh the page and let's look at our network tab and we're going to look at what the JavaScript is loading.
[00:11:34] So notice before it was only loading index.js everything was one bundle, right? But now I learned I load index.js then I load search params. So it's split into two separate JavaScript things. This is a megabyte point two again, this is development mode. So it's obviously going to be very large And then this is 38 kilobytes.
[00:11:53] Now, if you click on Luna here, it's gonna load for a hot split second and then notice down here it's gonna load details.js, and there you go. Now what's cool about this, let's say you don't have to do this. I'm just gonna do something to show you really quickly If I npm install moment which is a very large library, and I go into details.js and I import, moment as star from the moment.
[00:12:37] I don't know I've not used moment in a while so I don't remember exactly how to do this and then I'm just going to like console.log moment. Does not have like a default. Or is it stars moment. There we go, And then I run my server again. So I'm just doing this because I know moment is a very large library.
[00:13:14] Moment is only being used in details therefore parcel should pick up I was like, I only need to load moment, when details is being loaded, when I load an app I don't and so it's able to cut off that part of the dependency graph and only intelligently do that.
[00:13:28] Let's, again, I'm possibly famous last words here. So 38 kilobytes, if I click on this, yeah, notice that this is now significantly bigger. Go back, go away. 185 kilobytes and that's because it's smart to say like okay, cool, moment only goes with details, I'm only gonna include it with that one, pretty cool, right?
[00:13:58] So, again, this is one of the reasons that I quite enjoy React and code splitting all the kind of stuff. It's really fairly straightforward. We didn't have to do any extra song and dance and parcel in particular, just a smarter way to handle this stuff out of the box.
[00:14:13] This used to take quite a bit of setup to get it right in web Pack. It was possible and web pack definitely placed the way but parcel made it easy. All right, one more thing and then we'll take some questions after that. Head to modal.js, Or sorry not modal, we're going to do it in details.
[00:14:41] We're going to make it lazy load modal. So again, the same thing here. Get rid of modal here. We're gonna import lazy from react. We're gonna say const modal. Equals lazy function, return import./modal. That's it. We just now made modal lazy loaded. So let's actually move all this business now to modal.
[00:15:24] So I'm moving all of my moment stuff into modal. So that now modal will lazy load moment. So now if we go back over here, refresh your page a little bit. So, first of all, noticed that we did not add another suspense. Why? Cuz it's fine, we don't need to load suspense because it's being loaded or there's already a suspense in capturing modal because it's all the way up here.
[00:15:52] It'll bubble up until it hits the first suspense that it sees right now we could hear in details we could put another suspense in here and we would apply that one because we'd hit that one first because it just bubbles outward right. But we don't need to if we don't have to we don't have to if we don't need to, either way.
[00:16:13] All right, so here we load index we load details. Notice that we did not load some primes, for examples cuz we did not have the homepage first. And now, if I click adopt Luna, We get 170 kilobyte modal. So not only is it modal, which it sucks, objectively, it's a fat modal.
[00:16:32] Which no one especially likes. Or let's rephrase that it, is a lot of kilobytes modal [LAUGH] it's an expensive modal, yeah, that's a good way of putting it. But yeah notice again if you refresh the page here for a hot second it'll show you the loading here from suspense, Now obviously this is all local environment so it's going fairly fast but If this is going between here and AWS, that'll take more than a millisecond.
[00:17:05]
>> Will the same code work with Web pack?
>> The same code will look exactly the same with Web pack. It's been a while since I've done it with Web pack. So you'll definitely have to set it up differently but I don't think the codes gonna look any different.
[00:17:25] Or ES build or snow pack or any one of those because what I'm showing you here is just standard JavaScript there's nothing parcel specific in here. The question that I have is is there anything Web pack specific which I pretty sure the answer is no but you'd have to validate that's the case.
[00:17:44]
>> Can we use codes split in server side rendering.
>> Yeah, the reason why I didn't show you this together is it gets a little complicated. And when I say a little company gets pretty complicated, it's possible and difficult, I think is the answer to your question. So, you can now get code splitting is the name of the Repo here.
[00:18:12] If you go down to code splitting down here, there is code splitting. They click on that and you can see where we're at