Web Performance with Webpack

Code Splitting Demonstration

Sean Larkin

Sean Larkin

Web Performance with Webpack

Check out a free preview of the full Web Performance with Webpack course

The "Code Splitting Demonstration" Lesson is part of the full, Web Performance with Webpack course featured in this preview video. Here's what you'd learn in this lesson:

Sean demonstrates a simple code splitting example.


Transcript from the "Code Splitting Demonstration" Lesson

>> Sean Larkin: So let's look at a really simple example that, I try to portray what we're trying to accomplish here. So it's kind of pseudo code. And so at the top here, we're importing something called Listener, right? Just a module called Listener. And then down below, in the next line we have this variable that's assigned to a function that returns a dynamic import statement and a path to a module, right?

And what's really important is that it's assigned to a function that returns it, right? It's not equal to the import itself. And then so we have some pseudo code here that says, when some event that WarrenModalBeingLoaded is triggered, then we're actually gonna call to getModal inside of it.

And it returns a promise, when we recall this function. And then we actually get the code itself, the module itself, and we perform the functionality. Does that kinda make sense even if it's pseudo code? Are you feeling comfortable with that? Does anybody have questions so far? Yeah, go ahead.

>> Speaker 2: Did you call the getModal a second time? Does it make a request or is it-
>> Sean Larkin: Remember when we looked at the webpack runtime yesterday, what was the first three lines of code?
>> Speaker 2: Yeah.
>> Sean Larkin: You're right, the module cache, exactly. So answer is no, it doesn't call a second time.

It will request it but we find it in cache first and we just get the module back. But that's a great question, absolutely. I will jump back to the code and I'll show you an example with kind of the same context that we have been working on, so all right.

So let's say, I think it's just fair to actually have the development experience running. So I'm gonna do yarn dev, and I fixed presets in this branch, so it should work. Yeah, okay, let me pull up side by side so we can see it. Okay, so let's just say, I'll give this scenario.

Let's say we don't want to show the footer until we hit a button, right? So the naive approach might just be setting some styles or some attributes or not even having it on the dom. And then on the button click, then actually calling code, I just trying code this.

So for example, I could say, since our button is right here, we wanna do it after it's actually added. So button.addEventListener("click"), and then there is our event.
>> Sean Larkin: Okay.
>> Sean Larkin: So I think the naive approach would just be saying something like this, we just moved the document body.appendChild up, right?

And then boom, sounds good? But think about the problem here. So there's our functionality, but can we do better? Can we even not even load the footer code? Yes, absolutely, the whole point is that even though we aren't showing this and adding it to the dom, we can look and see that in our actual code itself like our bundle includes this code.

And we don't need it. So let's see, I bet we could find it. Essentially, it's module [SOUND], right? We can actually see it with the decorations. So here's our footer code right here. We don't need this upfront. So the process of code splitting is actually calling that module and having it loaded inside of here, in this addEventListener.

So what we're gonna do is we're gonna actually remove the footer call, right? And there's two ways that you can write this. So I'll do the first way and then I'll show you how you make it more reusable. Cuz you may wanna call or have this functionality multiple times.

So the first way would say, you could just use the dynamic import statement right here and say ("./footer").then. So webpack takes this dynamic import, and according to the spec, it converts into a promise behind the scenes. So this is gonna return a promise when you use a statement.

And then what you get is actually is the module itself, just as if you were accessing one of the named exports, except you get the default export by default. So I could say something like defaultExport. Some people say like footerModule, but you can name it whatever you want.

And what we'd say is document body.appendChild, we would say footerModule.footer, right? So now, we retained our functionality, nothing has changed. Except, if I was to reload this page and we look at our network request, oops. Now, you notice that when I hit that button, there is a second JavaScript file that gets loaded.

This file only contains your footer code. And we can identify that here. So if we look inside of this network panel, you can actually see right there. There is your footer. Does that make sense? This is code splitting. Nothing else is code splitting, but this process right here.

And so
>> Sean Larkin: I think the only thing that was new to me to get used to was understanding that you're introducing asynchronous behavior into your code base. And I mean, in this case it's a good thing, right? Because you're usually code splitting on asynchronous events. It's happening on a callback.

Or it's happening whenever another route is visited. And so it works well together. So let's say if you want to reuse this, you could instead take and just say. Instead of doing the exact call, what I like to do is, I just like to say up here, what would be the best way to do this?

So a common pattern for me, is I will take in just rename the exact identifier. So const footer instead of import footer = a function that returns a dynamic import
>> Sean Larkin: Sometimes I say like, get footer. So this is up to you. You can name it whatever you want.

I'll use get footer because then it's a little bit more easy to understand as a user, or if somebody diving into my code base for the first time. So this is the same thing, but the beauty is that now you can actually call this function multiple times. And just like I explained earlier to Jesse is that, if you were to call this again, it's not going to refetch the network request, it's gonna look into the module cache.

So what I wanna do is actually show you, and I wanna walk through the code. Here, let's hit the button, there we go. And you can see, even if I hit the button multiple times, nothing happens, right? It's just reaching into that bundle again.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now