Subscribe on changes!

`loadingComponent` property from `defineAsyncComponent` is ignored on SSR

avatar
Dec 18th 2022

Vue version

3.2.45

Link to minimal reproduction

https://stackblitz.com/edit/github-1aowkn?file=src%2Fpages%2FHome.vue&terminal=dev

Steps to reproduce

I encountered an issue with defineAsyncComponent loadingComponent property, it seems that the component provided is ignored when using SSR and ClientOnly tricks.

<script setup>
import { ref, defineComponent, h, defineAsyncComponent } from 'vue';

const ClientOnly = defineComponent({
  setup(_, { slots }) {
    const show = ref(false);

    onMounted(() => {
      show.value = true;
    });

    return () => (show.value && slots.default ? slots.default() : null);
  },
});

const ComponentA = () => h('div', { style: 'background: red' }, 'Component A loading');
const ComponentB = () => h('div', { style: 'background: blue' }, 'Component B loaded');

const AsyncComponent = defineAsyncComponent({
  loader: () => new Promise((res) => setTimeout(res, 5000)).then(ComponentB),
  loadingComponent: ComponentA,
  delay: 2000,
});
</script>

<template>
  <ClientOnly>
    <ComponentA />
    <ComponentB />
    <AsyncComponent />
  </ClientOnly>
</template>

What is expected?

In the example above, using AsyncComponent should render nothing for 2 seconds (delay) then render ComponentA for the next 5 seconds (the loadingComponent) and then, after a total of 7 seconds, display the ComponentB

What is actually happening?

Actually, it renders nothing for 7 seconds (delay + loading time) and then displays the ComponentB

System Info

  System:
    OS: Linux 5.15 Ubuntu 20.04.5 LTS (Focal Fossa)
    CPU: (16) x64 AMD Ryzen 9 5900HS with Radeon Graphics
    Memory: 9.14 GB / 15.33 GB
    Container: Yes
    Shell: 5.8 - /usr/bin/zsh
  Binaries:
    Node: 18.9.0 - ~/.nvm/versions/node/v18.9.0/bin/node
    Yarn: 1.22.19 - ~/.nvm/versions/node/v18.9.0/bin/yarn
    npm: 8.19.1 - ~/.nvm/versions/node/v18.9.0/bin/npm
  Browsers:
    Chrome: 108.0.5359.124

Any additional comments?

avatar
Dec 18th 2022

That's because it's nested in <Suspense>, so placeholder/loading fallback content is now <Suspense>'s job