Lazy Load Routes

Part 3 of 4 in our Creating Your Own Router series.
Written by Alex Jover Morales
Lazy Load Routes

Lazy Loading and Code Splitting are two of the main points of the PRPL Pattern, a pattern named by Google which intent is to to provide some structure to make the initial load of a Progressive Web App (PWA) as fast as possible, boosting the performance.

The PRPL pattern stands for:

  • Push critical resources for the initial URL route.
  • Render initial route.
  • Pre-cache remaining routes.
  • Lazy-load and create remaining routes on demand.

User engagement is dependant on how satisfied the user is using your app, and performance takes a great part. We can separate web performance in:

  • Actual performance: describes how long take the functional actions and states of an app to be in a ready state. Ajax calls durations or app loading time are some examples.
  • Perceptual performance: describes how fast and smooth those actions and states of an app are perceived by the user. It sums up to the actual performance. In other words, if the actual performance increases, the perceived performance increases as well, but when actual performance cannot be increased then the user experience can be improved by increasing the perceptual performance. Time to Interactive, Perceptual Speed Index and animations are some examples.

Lazy loading on routes increases the actual performance, being an important tool to improve the user experience of a web app.

Use Lazy Loading on the Router

You might think this can be a pain to implement, but... What if I tell you that this router already works with lazy loaded routes out-of-the-box?

Yes, that's right. Vue.js template’s compile to render functions, which get a createElement function as a parameter that allows to pass a function returning a promise. An example would be:

render(createElement) {
  return createElement(() => Promise.resolve('<div>Hey boy</div>'))
}

That way, we can use the dynamic import to load and render a component asynchronously because it returns a promise with the module as the payload.

Given that the <component> element gets compiled to a render function, in AppRouter.vue we can remove the static imports and instead use dynamic imports:

// AppRouter.vue
const routes = {
  "/": () => import("./Home"),
  "/articles": () => import("./Articles")
};

If you try it out and open the network tab on the browser's devtools, you'll see it's working and creating separate chunks with a name like 0.chunk.js which are loaded as you press the Next button.

Note: you must try it locally, you won’t see any chunks in the network tab if you try it from the CodeSandbox example.

Wrapping up

If you've reached this point, that means you've built a router in Vue.js yourself! It all started creating a basic router from scratch, but hey, the router is component based, uses the HTML5 History API, and it can be easily used for lazy load code-split routes! It wasn't hard, right? Vue.js indeed helps making it that easy.

For now, the router is tied to our app, but we’ll see how to make it a Vue.js plugin so it’s 100% reusable and exportable to an npm package.

Learn Vue.js 3 With Vue School
  1. It would be nice with a tutorial on how to split a vue application in different micro-frontends. So that different parts of the single page application can be hosted on separate urls, but maybe using the same vuex store somehow?

Leave a Reply

Your email address will not be published. Required fields are marked *

Up Next:

Enhance Router To Work With Single Page Applications

Enhance Router To Work With Single Page Applications