JavaScript Performance JavaScript Performance

Component Lazy Loading Solution

Check out a free preview of the full JavaScript Performance course:
The "Component Lazy Loading Solution" Lesson is part of the full, JavaScript Performance course featured in this preview video. Here's what you'd learn in this lesson:

Steve walks through the Solution to the Component Lazy-Loading Exercise.

Get Unlimited Access Now

Transcript from the "Component Lazy Loading Solution" Lesson

[00:00:00]
>> Steve Kinney: Getting this done is effectively the same, as what we did last time. We'll make a loadable note view component.
>> Steve Kinney: At JS. I'm actually gonna do a little cut and paste action from the previous one. And so, import react and loadable. We're gonna use the same loading component.

[00:00:28] Like I said before, you're not limited to one loading component. Different pieces of UI have different shape. Maybe it's a spinner, maybe it's a skeleton of a thing. I would be a little bit more customized with my loading ones. But for this, I think it'll work. In this case, we're actually gonna bring in the NoteView, cool.

[00:00:53] And then, in the NoteView container, I'm just gonna swap this out for the,
>> Steve Kinney: LoadableNoteView, cool. Let's take a look at that in action over here. I'm actually gonna go back to the initial page. And, we can go ahead. I briefly see loading. I get the next component.

[00:01:21] And then, I hit Edit, I load each component progressively, as I need it. Kinda thing I mentioned earlier, but I wanna highlight a little bit, is that the import syntax is not react-specific, it's not anything-specific. I could have used the import for loading, just load-dash, or anything along those lines.

[00:01:41] You say what file you want to import. You get back a promise that resolves with whatever the default is, or the entire package is there. So this could be, these are reaction components. This could be anything. And you don't have to use react-loadable. You can use this code wherever you want.

[00:01:57] So I could, for instance, implement a feature which is like, hey, listen, I know that if they went to the note view, that they're probably gonna wanna go to the editor next. So when that component does mount, I can say component did mount, import the next file, kick that off beforehand.

[00:02:14] Effectively prefetching any of those assets. Let's actually take that for a spin real quick. So we'll go to the note view. I'm going to just slight a refactoring, cuz this is one of those stateless functional components. We'll grab all of this right here. And we'll say, actually hold on.

[00:02:39] Give me one second, Class NoteView.
>> Steve Kinney: Extends React.Component.
>> Steve Kinney: Put back in the render method.
>> Steve Kinney: Yeah, this is why I turned into a stateless function, cuz every [INAUDIBLE], you should make that a stateless functional component. I'm like, you leave me alone. We'll say, component DidMount. And in here, this is where we can actually begin to load the editor, in this case.

[00:03:20] So we'll say,
>> Steve Kinney: Now, if I needed the editor code immediately, I could say then, and I could have, if is a regular file, begin to use it, and here, I can even use async await. So I can say async load whatever, and begin to use it. In this case, I really don't.

[00:03:41] This is basically just a prefetch queue, which is, I'm saying, hey, if they loaded this note view, they're probably gonna wanna load the editor next. So why don't you kick off that load? So now, hopefully, they won't see any load times, what so ever, when it comes from going from the no view to the editor, cuz we will in fact have kicked that off, beforehand.

[00:04:00] So let's go ahead, and try that out.
>> Steve Kinney: We'll actually go back one. Cool.
>> Steve Kinney: Oops, something is angry with me. If you don't export stuff every file, you'll get in trouble.
>> Steve Kinney: Support default Note view.
>> Steve Kinney: Cool. So I'm actually go back to the beginning, and will highlight some extra tools while we're doing this.

[00:04:42] I mentioned in the beginning that, yeah cool, you're on an expensive computer with a fast Internet connection, and you're like, it'd be great to be heavy in 150 for my users, and see what any of that's like. So what you can do in the network pane, is you can actually simulate different network connections.

[00:05:01] Like fast 3G, slow 3G, and offline, and add a bunch of stuff along those lines. And there's actually another one in the performance section, which I think is really powerful. You can also throttle the CPU. So you wanna imagine what it's like on a slower mobile device, you can go to 4x slower or 6x slower, which is incredibly cool.

[00:05:19] And those will only be true when the dev tools are open, so if you forget to turn it off, it's gonna be okay. But just to make a point, what I wanna do here, is I wanna change this to maybe just a little bit more, slow the Internet down a little bit.

[00:05:36]
>> Steve Kinney: Cool, so we're loading. You can see when I click on this, it's a little bit slower. We loaded it. We can see, I've also loaded some additional bundles. When I hit Edit, it's instantly there. I prefetched the editor. Now, is that the right thing to do and should you do it, in every component?

[00:05:50] Well, if you do it in every single component while [INAUDIBLE] amounts, you will effective loaded the entire Africa [INAUDIBLE] where they're going. So you have to be a little [INAUDIBLE] about it, but you can theoretically reduce some of that loading time, by prefetching those assets. This is not a react specific thing.

[00:06:06] This is a JavaScript thing that you can do with Webpack, and a lot of other loaders. But yeah, you can get stuff as you need it, which is not in the initial bundle. But you can then kick off, prefetching, so that it seems like you're not doing that.

[00:06:18] So effectively, you get to have your cake, and eat it too. Because I do it, it's the same thing as world change did for us, right. Going and getting the thing, and getting ready for it, before we need it, gives that kind of an instantaneous feel to the user.

[00:06:29] Where they don't have to, we cut down on the low time, by getting the initial bundle smaller, but we originally pay the price, which is response time to an app. Cuz now I have to go get it, especially on a slower connection. But in this case, with prefetching, we can both shrink our load times and shrink our response times, which is really, really cool.

[00:06:48] Let's go take a look at the bundle that we ended up producing.
>> Steve Kinney: And what we hope to see, is yet another bundle created, and we'll kind of get some statistics on what we ended up doing. But simply, we actually didn't, if you also include me saying words, we didn't spend a lot of time implementing this.

[00:07:14] Yet, we initially cut down a third of our bundle after cutting down a tenth of our bundle. Using a codemirror, and the components that use it, become their own bundle. My actual main bundle that I'm sending over the wire now, is 187 kilobytes. Right, that is a fraction of the initial amount.

[00:07:34] Somebody that tried to ask me for like, what is the purpose of that 300 kilobytes, it's just a line in the sand. It's just a goal to get each chunk under 300 kilobytes. Aria Osmani, actually has his goal set at 100 kilobytes. Right, which seems undoable, but we've got pretty close.

[00:07:52] Now granted, there's not like a lot left to cut out here. I could do it, I could do something like trigger it. I probably get reaction about our lazy load, but we're trying now. But it is kind of really cool. We're able to see significant gains relatively quickly, and fairly easily.

[00:08:12] And then, see how we could preload and prefresh assets, to make this effectively invisible to our users.
>> Steve Kinney: One moment. Got a little ahead of myself in the slides there. All right, we're back. So I do wanna drive this point home, a little bit more. Which is okay, cool.

[00:08:39] It's a react app. But I have a big angular app, or anything along those lines. Or an amber app or a backbone app. And so, I feel like the first few times I heard about all this lazy load and code splitting, I was like, I'm overwhelmed, this is never gonna happen.

[00:08:58] We do a rewrite, I'll totally implement all of this. But, we can see that all we need to do is take a given component, use something like react loadable, and swap it out, right? This is something you can go, and you can do tomorrow in your application. And start figuring out, do the bundle, visualize it.

[00:09:12] What are the biggest pieces of pain, where's the most agony, right? It may not be the biggest one in there, but if you know that that is a frequently loaded one or low hanging fruit, you could implement this tomorrow. And it's not just react specific. This is another [INAUDIBLE] grid.

[00:09:27] This is their split out code base, after they've implemented this. And there are a backbone app. Right, it's back on a marionette mostly. Backbone comes from a time before any of these fancy tools existed. So if they can do this with their application, and it did not take them very long.

[00:09:45] So you can see that they still have an initial bundle. The main bundle is, actually that second from the left at along the top. And so they're now loading D3, immediately. They're now loading jQuery immediately, right. They're just loading the pieces they need to get the initial page up, and then as you navigate around, they can get you all the different things that they might need, all the different, like SCSS files.

[00:10:08] If they do need jQuery or D3 that can get those. And if another bundle requires the same one, you've already loaded it. So it's not like you pay this tax of getting it every time, it's just progressively loading the app. Everything you have in memory, stays, so you don't have to pay that network load cost.

[00:10:25] You get to cut down on your initial load cost, and you get to cut down on your initial parsing cost. So all of the kinda things we were trying to solve for, over the course today. Like rendering, can still be a thing that you need to deal with, cuz that's you changing the world.

[00:10:37] But, by shifting less code, our code is faster, right, cuz we're doing less of something. So this is the kind of the visualization. You can see that their main bundle is 39 kilobytes. Right, that's it for the initial bit of code that they ship over the wire. And then they get pieces as they need them, slowly but surely.