vuedose.tips(翻译系列十五)
Dynamic Imports in Vue.js for better performance
Today we have here Paul Melero, a great web developer and friend who also loves teaching other devs.
Did you know that he’s the author of the Testing Vue.js Components with Jest Spanish translation? Don’t expect too little from him!
Let’s jump into Paul’s tip!
I bet you are already familiar with the terms “code splitting” and “lazy loading”. Let’s take the latter definition from Webpack’s docs:
Lazy, or “on demand”, loading is a great way to optimize your site or application. This practice essentially involves splitting your code at logical breakpoints, and then loading it once the user has done something that requires, or will require, a new block of code. This speeds up the initial load of the application and lightens its overall weight as some blocks may never even be loaded.
This kind of feature should be done by default by the frameworks we use, as some people have suggested. (Also in the React ecosystem)
只要有可能,我建议使用动态导入来导入组件。必要时,它们将被延迟加载(由Webpack加载)。
// Instead of a usual import import MyComponent from "~/components/MyComponent.js"; // do this const MyComponent = () => import("~/components/MyComponent.js");
当使用Webpack捆绑您的应用程序时,您可以使用不同的方式来处理模块(ES模块,CJS,AMD…)。如果选择ESM方式(推荐),则将具有以下语法:
import MyComponent from "~/components/MyComponent.js";
Notice that there are several use cases where we would like to use asyncronous components. As explained by Alex Jover inthis article:
-
In component importing
-
In Vue Router, for components mapping
-
In Vuex modules
Let’s take a look at the syntax and focus on the import part.
If you are using Webpack (or Parcel!), that syntax is going to be transformed on compilation time and these tools are going to usePromises to load asynchronously your assets/modules/components.
Why the need of an arrow function, you might be wondering: As Alex explained, we need to wrap the import with an arrow function to be resolved (remember, promises…) only when executed.
To demonstrate that they are fully lazy loaded I’ve prepared a repository (using Nuxt.js). It has 2 pages, each of them use different techniques (With and Without dynamic imports) to import 2 components (component “A” and component “B”).
We will see how, when loading the page with dynamic imports, webpack loads 2 separate files after the navigation. But, the page component itself (/without) using regular imports, is heavier because it loads everything at once.
imageImage showing network waterfall when navigating to both pages. And the differences between both techniques (with and without dynamic imports)
Yes, by using this technique, Webpack will create separate files (“chunks”) to load them when needed (lazily). Custom chunk naming can be done with Magic comments but that will be the subject of another article
imageImage showing the result of nuxt build. See how different chunks are created for components A and B when dynamic imports are used!
That’s it!
For a deeper exploration of code splitting techniques check:
-
De facto linked article by Anthony Gore: https://vuejsdevelopers.com/2017/07/03/vue-js-code-splitting-webpack/
-
Google’s web fundamentals article by Addy Osmani and Jeremy Wagner about code splitting: https://developers.google.com/web/fundamentals/performance/optimizing-javascript/code-splitting/
-
Webpack docs: https://webpack.js.org/guides/code-splitting/