Search code examples
asynchronousvuejs2vue-componentasync-components

Vue async components are loading without delay regardless of the the 'delay' parameter


I am using Advanced-Async-Components to load async component after loading of the app. So I have tried the following code:

Index.vue

<template>
    <div class="">
        <Async></Async>
    </div>
</template>

<script>
    // async component
    import LoadComp from '@/components/Loading'
    import ErrorComp from '@/components/Error'
    const Async = () => ({
        // The component to load. Should be a Promise
        component: import('@/components/Async'),
        // A component to use while the async component is loading
        loading: Load,
        // A component to use if the load fails
        error: ErrorComp,
        // Delay before showing the loading component. Default: 200ms.
        delay: 4000, // <--- this is not effecting the loading of component
        // The error component will be displayed if a timeout is
        // provided and exceeded. Default: Infinity.
        timeout: 3000
    })

export default {
    components: {
        Async
    }
}
</script>

Async.vue

<template lang="html">
    <div class="">
        Lorem ipsum dolor sit amet, con .... very larger string/data
    </div>
</template>

<script>
export default {
}
</script>

<style lang="css">
</style>

The above code works fine but it has no effect of delay parameter (Index.vue). According to official docs delay is Delay before showing the loading component. It should load the component after 4000ms but it loads instantly.

Why is this happening?

Is there any other way to achieve this apart from using setTimeout?

Additional Info

I used webpack template to build the project using vue-cli

Vue version : ^2.4.2

Solution

  • This is happening because the delay option sets the amount of delay in milliseconds before showing the loading component, which is the component you have specified via the loading option to display while the async component is loading (the documentation is poorly-worded on this one).

    In the below example, two async components are loaded after one second. The first has no delay and the its loading component (LoadingComponent) will display immediately. The second has a delay of 500, meaning that after half a second, it will display its loading component.

    const LoadingComponent = { template: `<h1>Loading...</h1>` }
    const NumberBoxComponent = { template: `<h1>123123</h1>` }
    
    const AsyncComponent1 = () => ({
      component: new Promise((resolve) => {
        setTimeout(() => {
          resolve(NumberBoxComponent)
        }, 1000)
      }),
      loading: LoadingComponent,
    })
    
    const AsyncComponent2 = () => ({
      component: new Promise((resolve) => {
        setTimeout(() => {
          resolve(NumberBoxComponent)
        }, 1000)
      }),
      loading: LoadingComponent,
      delay: 500
    })
    
    new Vue({
      el: '#app',
      components: {
        'async-component1': AsyncComponent1,
        'async-component2': AsyncComponent2
      }
    })
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.4/vue.min.js"></script>
    <div id="app">
      <async-component1></async-component1>
      <async-component2></async-component2>
    </div>

    If you want to delay the actual loading of the async component, you should use setTimeout.