I have split my app into multiple chunks with webpack's code splitting feature so that the entire application bundle isn't downloaded when the user visits my webpage.
The chunks that some routes require can be reasonably large and may take a noticeable amount of time to download. This is fine, except the user is not aware that the page is actually loading when they click an internal link, so I need to somehow display a loading animation or something.
My router is configured like this:
[ { path: '/', component: () => import(/* webpackChunkName: 'landing' */ './landing.vue'), }, { path: '/foo', component: () => import(/* webpackChunkName: 'main' */ './foo.vue'), }, { path: '/bar', component: () => import(/* webpackChunkName: 'main' */ './bar.vue'), }, ]
Advanced Async Components in the Vue.js guide shows how to display a particular "loading" component while the component is being resolved -- this is exactly what I need, however it also says:
Note that when used as a route component in vue-router, these properties will be ignored because async components are resolved upfront before the route navigation happens.
How can I achieve this in vue-router? If this is not possible, lazily-loaded components would be pretty much useless to me because it would provide a poor experience to the user.
Lazy loading (also called on-demand loading) is an optimisation technique for the online content, be it a website or a web app.
To lazy load the component, we will use the import() method inside an async/await function. The above function first clears the container; otherwise, on every click of the button, the new instance of GreetComponent would be added in the container.
Lazy loading is the technique used in optimizing your web and mobile apps, this works by rendering only needed or critical user interface items first, then quietly rendering the non-critical items later. As we build code components the application grows, and the bundle gets very cumbersome in size.
Lazy loading is the process of loading components, modules, or other assets of a website as they're required. Since Angular creates a SPA (Single Page Application), all of its components are loaded at once. This means that a lot of unnecessary libraries or modules might be loaded as well.
You can use navigation guards to activate/deactivate a loading state that shows/hides a loading component:
If you would like to use something like "nprogress" you can do it like this:
http://jsfiddle.net/xgrjzsup/2669/
const router = new VueRouter({ routes }) router.beforeEach((to, from, next) => { NProgress.start() next() }) router.afterEach(() => { NProgress.done() })
Alternatively, if you want to show someting in-place:
http://jsfiddle.net/h4x8ebye/1/
Vue.component('loading',{ template: '<div>Loading!</div>'}) const router = new VueRouter({ routes }) const app = new Vue({ data: { loading: false }, router }).$mount('#app') router.beforeEach((to, from, next) => { app.loading = true next() }) router.afterEach(() => { setTimeout(() => app.loading = false, 1500) // timeout for demo purposes })
Then in the template:
<loading v-if="$root.loading"></loading> <router-view v-else></router-view>
That could also be easily encapsulated in a very small component instead of using the $root
component for the loading state.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With