How to Prefetch Lazily Loaded Vue Components — Transcript

Transcript of the free Vue.js lesson How to Prefetch Lazily Loaded Vue Componentswatch the video lesson.

In the last lesson, we saw how we could separate a component into its own chunk so that we could load that chunk only when it's actually needed on the page. This works great for my fast connection. However, what if we were working with a slower internet connection? Let's turn on throttling in order to emulate a 3G connection and then press the button again.

This time, there's over two seconds between me hitting the button and the component actually displaying to the page. That's not a great user experience. Now, we could use the loading option that we saw in the last lesson to at least provide a loading indicator to the user that something is happening, but I think we can do even better than that. How?

Well, what if we could prefetch this component chunk in a non-blocking way so that it doesn't prevent the initial page load? but it also doesn't wait until the user actually clicks the button to attempt the download. Okay, let's check out the for-prefetching-begin file inside of the view app, and I'll show you how to do exactly that. Here is that callback function that we provided to define async component in the last lesson.

Let's cut that and extract it to a function called loadComponent. then we'll pass load component to define async component. This now works exactly as before, but now I have a function available to me to load the component any time that I'd like. Okay, so what if we put an event listener on the button to listen for the mouse enter event?

Then we could load the component as the user's mouse enters, that way the component is more likely to be ready once the user actually clicks. Let's give this a try. I'll turn off the throttling for just a moment, reload the page, careful not to mouse over the button here as I come back over to the network tab, then I'll turn on 3G throttling once more. Okay, so I'll do this fairly quickly as a normal user would.

With the page focused, I'll hover over, which initiates and then click and cool. This time the download of the component still took two seconds, but the component displayed on the page almost as soon as I hit click because it had already had a couple of seconds to start the loading process. The advantage of this approach is that we only load the component if there's fairly clear intent from the user that they're going to click the button. We could get even a little bit more eager though, and we can load the component directly inside of Script Setup.

Since we're doing that, let's remove it from the mouse enter event. And what this does is it will load the async component as this current component is being set up. But this, since we're not awaiting anything, will not block the rendering of this current component. time here.

And we'll label this load. Then I'll add a console time end. basically at the very end of our template right here. Using console time and console time end is a great way to measure how much time has passed between two points within your code.

Okay, let me give the page a refresh again. It is going pretty slow because we still have the throttling in place. Great. So now when I hit toggle code splitting example, it does load immediately.

That means our preload is working exactly as expected. But was the prefetch preventing my page component from loading? 966 milliseconds between that time start, where we started loading the preloading the component, and the time end, where the rest of the current component was being rendered. That's a far cry from the two seconds it takes to preload the component.

So certainly, this is not blocking. By the way, don't worry that the console has a warning, timer load does not exist. This only applies because we hit the toggle code splitting example button, which caused our parent component to re-render. And on that re-render, the timer hadn't been initialized.

966 seconds is accurate. What if we wanted to do the same thing for our page routes? Well, we totally could. I'll copy the load component function here, paste it, and call this one load home page component.

Then we will point the import statement at that page. Finally, we'll just preload it directly inside of setup. Once again, making sure not to wait for this to finish. The reason that's useful in this case, is because we have a go home router link that goes to the home page at the end of this current page.

So over in the browser, I do still have throttling on, but clicking the home page link works immediately because I've already preloaded it. What about preloading lazy components in Nuxt? Is that possible? Let's open the prefetching begin page that lives inside of the Nuxt app.

Then over in the browser, I'll open up my Nuxt app to that page. One of the beautiful things that Nuxt is going to do for us automatically is preload any page that has a corresponding Nuxt link on the current page. And more precisely, has a Nuxt link that is visible on the current page. Let's open up the network tab here.

I'll disable throttling just to go a little bit more quickly in the video. and then I'll remove our filter, filtering out just the example component here. Okay, so I'm on the prefetching begin page, but look what happens when I click on the hamburger menu to show the main menu. All of a sudden, we have all of these page components prefetched for us, meaning that they're ready to go as soon as I navigate to a new one.

That's what I mean when I say Nuxt prefetches our page components for us when a Nuxt link to that route appears on the page. Do note, though, that this is only preloading the JavaScript. It's only downloading the JavaScript. It's not executing it.

So any data you might be loading, you might be fetching inside of that prefetched pages script setup block is still going to have to be fetched on navigation. Furthermore, if I go back to the prefetching begin page and then edit this page inside of my IDE, you'll find that we have a little bit more control over when the page for a corresponding Nuxt Link is prefetched. Number one, we could turn it off altogether with the prefetch prop set to false, or set the prefetch on prop, which allows us to decide when we want to prefetch it, either on visibility of that Nuxt Link or on interaction, AKA mouse over that Nuxt Link. Visibility is the default.

Let's see how the interaction works. Save. Over in the browser, I'll refresh, open up my network tab again and clear it out. And this time when I hover over the go home link, we do have that page component prefetched.

That's prefetching page components in Nuxt, but what about prefetching any other component? This is totally possible as well, but it's a little bit tricky. You would think that we could preload this lazy split example component just as it is. However, we have to make one change before we're able to do so.

global. This forces the code split example component to always be split into its own chunk. With that in place, I can call preload components inside of my page. passing it an array of all the components I want to preload.

In this case, the code split example component. Once again, just like in our vanilla view app, we do not await for this to complete so that it happens in a non-blocking fashion. Over in the next step, we'll open the network tab one last time, clear it out and give the page a refresh. Let's narrow this down to the example component.

Notice it is fetched immediately here on page load. And when I click the button, we don't have to load in any new component. It's already available for use. Code splitting some of your components into chunks and even preloading some of those chunks can be a great performance booster for your site.

Just remember the warnings that we talked about at the end of the last lesson. You can go overboard doing this and cause waterfalls that slow your site down. So just don't go crazy with it. And remember to only lazy load these chunks that are conditionally rendered to the page.