We've seen how Next.js optimizes our images,
for example by converting them to
a more modern format like WebP,
which results in a smaller file size.
That kind of optimization is done on the server.
But using the Image component also
enables browser optimizations,
like lazy loading.
Now, this page is not actually the
best example for this feature.
In fact, we've seen that we currently
get a warning in the Console
telling us to add the "priority"
property to our image.
That's because in this page
we only have one image,
and it's displayed near the top,
so it should be loaded by the
browser as soon as possible.
Let's do what the warning suggested,
and set the "priority" prop, that is a "boolean",
so we can just write the prop name,
which in JSX is equivalent
to setting it to "true".
If we save and reload,
we should see that the "img" no longer
has "loading" set to "lazy",
but quite the opposite:
it has "fetchpriority" set to "high",
which is a way to tell the browser that
it should load this image as soon as possible.
And this will prevent that warning
that we were seeing in the Console.
Now, like I said, the ReviewPage
is not the best example
for explaining lazy loading.
Let's take a look at the Reviews page instead.
Here we have multiple images.
We know that we fetch 6 reviews,
so there will be 6 images.
But notice that only 3 of them
are currently visible;
in fact it's more like two and a half.
We need to scroll down to see the rest.
So loading all 6 images straight
away is a bit of a waste,
because the user will only
see 3 of them initially.
Our page could be displayed more quickly
if the browser only loads
the visible images first,
and waits until after the initial page
was rendered to load the rest.
This is what's called "lazy loading".
Now, let me go and open the
code for the ReviewsPage.
This is another one of the files for
which ESLint was showing a warning
because we're using the "img"
tag rather than Next Image.
Let's start by inspecting these images
as they are at the moment.
You can see that the src on this element
is the original Strapi URL.
What we're more interested in right now
is actually in which order the images are loaded.
Let's go and do a hard reload
and then look at the various requests.
Note how, at the moment, all the images are loaded
right after the HTML document, the fonts,
and the stylesheet,
and before any JavaScript files.
Now, to be more accurate
we should look at the Waterfall column
to see the timing of each request.
But by default requests are
sorted by their start time,
so looking at the order in
the list is good enough.
Now, let's go and modify our code
to use the Next Image component instead,
that we need to import into this file.
Let me sort these imports.
Anyway, let's go and see how
this affects our images.
The Next Image component automatically
sets "loading" to "lazy".
Let's see what difference this makes
in terms of network requests.
You can see that the images are now loaded
after the "main-app.js" file,
while earlier they were before
all the JavaScript files.
This shows how lazy loading causes
them to be requested later
in the process of fetching all the page resources.
Now, be aware that different browsers
can work differently
when it comes to lazy-loading images.
Chrome may behave in a different
way from say Firefox or Safari,
and mobile browsers probably differ
from desktop browsers as well.
So this is just to give you the general idea.
Anyway, by loading all images lazily however,
we'll again see the warning about priority.
Let's examine this message in more detail.
It says that the image for "hades"
was "detected as the Largest Contentful Paint"
or "LCP" for short.
Now, the "Largest Contentful Paint"
is one of the metrics used
to measure how quickly a web page loads.
It's defined as the time it takes to render
the largest image or text block
visible on the page.
If we look at our Reviews page,
the first image is in fact
the largest bit of content
that's displayed right after we load the page.
So, it's not a good idea to lazy-load that image.
We want the browser to load it
as soon as possible instead.
Now, there's actually more than
one image on this page
that's visible without scrolling.
In fact, how many images will be "above the fold"
also depends on the screen size.
On a large browser window,
we see all 6 images in full.
So, which images should we lazy-load?
We just don't know exactly how
many will be "below the fold".
In practice, it's ok to use lazy-loading
for most of them anyway.
They will still be loaded by
the browser eventually.
What I usually do is set the priority
only on the first image in a list.
When using "map" to iterate over an array
the callback function receives
an optional second argument
that is the "index" of the current
element in the array.
So we can easily set the "priority"
only on the first image
by passing "index === 0" as
the boolean expression.
This will be true only for the first element.
Let's see if this works.
If we inspect the first image again,
you can see that it now has "fetchpriority"
set to "high".
While if we go and check the second image,
this one has "loading: lazy".
And it will be the same for the other images.
This way we avoid the "priority" warning.
But we'll still use lazy loading
for most of the images,
as we should see in the network requests.
The first image is loaded right
after the stylesheet.
While the rest of them are deferred until later.
And by the way, they've also been
converted to "webp" and resized,
reducing their file sizes,
as explained in the previous video.
But the main focus of this
lecture was lazy-loading,
that's enabled by default when using
the Next Image component.
We can selectively disable this feature
by setting the "priority" prop.