- [Instructor] Earlier in the course,
I talked about lazy loading images
and other media assets to improve performance
by only loading them into the browser
if the user got to them
well, we can sort of use that same idea
to lazy load JavaScript modules
and their associated assets only
when they're interacted with and needed.
This is achieved using the import statements in JavaScript
and it's best explained through a practical example.
So I built a very, very basic example.
Let's say I have an app and the app has a button.
When I click on that button
a gallery pops up showing some images,
I guess that this is a very basic example.
Now, imagine this button here is something far more complex
some advanced JavaScript feature like a dynamic gallery
or a shopping cart or an advanced form
or something that could require a lot of JavaScript
or maybe even a lot of data like an image
or a video or something like that.
The straightforward way of making this effect would be to
just load everything into the browser
and then hide the features that you want to appear.
That way when the user clicks on the button
the content is revealed and things work as expected.
But what if this feature is something only
some users will interact with like a shopping cart
or product details for a product page
or a form or something else.
If the user doesn't interact with it
we really shouldn't be loading the JavaScript
and all these extra assets into the browser at all.
We should be saving the user's bandwidth if we can.
That's where lazy loading JavaScript with
the import statement comes in.
If we jump to the code for this example
you'll see in index dot HTML,
I'm calling in a single file called script dot JS
sits over here
and script dot JS, just monitors the button,
and then says if we click on the button, then do something.
When the user clicks on the button
this import statement is used to import
the module in an external file on the fly.
The module sits in this file called module JS.
It's called gallery
and it's export it all the way down here at the bottom
export default gallery.
That's why the import statement works.
Now, this module is really basic.
All it's doing is creating a section element
then putting some HTML content inside it.
And that HTML content is a set of figures
that call different images.
And this is why we're downloading all these images.
If you look a little bit closer at the actual code
and script dot JS, you'll see we're using a promise
here we're saying import module JS.
So that imports the entire module JS file.
Then once that file is imported
go to the object that was imported
and find the default of the object,
that would be the default export down here
export default gallery.
In this setup, I call that default gallery
and then I call gallery as a function.
Let's look at what's actually happening in the browser.
So in Firefox I'll inspect elements
and open the network monitor
and I'll reload
and you'll notice at the top,
we're loading in the HTML document
the style sheet and script dot JS.
Now watch what happens when I click the button.
All of a sudden we get new stuff down here
in the network monitor.
Now we've imported module JS.
That was the module file
and module JS then calls in the images
Belle, Oscar, Sergeant and Spring.
That means I'm not just lazy loading in the JavaScript.
I'm also lazy loading in the images only
when the user interacts with them
this is kind of the whole point.
We're now conditionally loading JavaScript
and other associated assets
only if the user interacts with them.
Now, there are two different methods for
lazy loading JavaScript modules like this
the promise I just showed you here
and we can also use an async await function.
So if I comment out this and scroll down a little bit
I've set up the same example using async await here
we set up an async immediately invoked function expression.
Then inside the async we say await import
meaning the browser will now sit
and wait until the import is completed.
Then grab the default and set it to a gallery.
So we get the gallery expert and then run gallery as before.
If I save this, go back to the browser and reload
and click the button.
You'll see it works exactly the same way.
These are just two different approaches
to doing the exact same thing.
Now, the cool thing about this whole concept is
we can use this with any JavaScript module
including external JavaScript modules.
So if you have an external third party library
on a CDN somewhere
something like the rough library, for example
and that library offers a JavaScript module often referred
to as an ESM module
you can call it in using the same approach.
That's the last example I've set up here.
So if I uncommon this,
we can take a look at what happens
again we set up an async
immediately invoked function expression.
Then we call in advanced JS.
We grab the function inside that's called drawboxes
I mean run drawboxes,
advanced JS then in turn,
sets up an async function.
And this async function goes
and imports a package from a CDN called rough.
Rough allows us to draw roughly shaped shapes
for prototyping purposes.
And this example starts to indicate why
it's important to use this lazy loading approach.
Because here we have a lot of JavaScript.
There's a lot of settings.
There's a lot of stuff going on
and we're importing a large external library to
make it work.
And this should really only happen in the browser
if the user's actually going to interact with it.
So we also have two imports now
we have first import of advanced JS
and then advanced JS in turn imports another file
so we're chaining the imports.
Let's see what happens when I run this in the browser.
If I first just click on the button
we get this rough drawing of some boxes.
This is what the rough library does.
It allows me to make hand drawn boxes in the browser.
Now, if we look at the inspector again,
go to network and reload,
you'll see the same thing as before happens.
First, we load in style script and the HTML document.
And then when I click the button, we load another stuff.
Only this time we're first loading in advanced JS,
and then advanced JS is loading in rough dot ESM dot JS
from this external library.
And that means I'm not chaining my events,
lazy loading in JavaScript
and getting everything to work conditionally
on the user's behavior.
So I'm saving the user a ton of data
and only pushing content to the browser when it's needed.