Increase of Vue3 user experience: asynchronous component and suspend component

By Matt Maribojoc
Translator: front end Xiaozhi
Source: stackabuse

There are dreams and dry goods. Wechat search [Daqian world] pays attention to this dish washing wisdom who is still washing dishes in the early morning.

This article GitHub https://github.com/qq449245884/xiaozhi It has been included. There are complete test sites, materials and my series of articles for the interview of front-line large factories.

Lazy loading components is an easy way to improve the user experience of applications, especially when our code package is large or the user connection speed is slow.

Vue3 has introduced some new features that can help us achieve a friendly user experience by improving the asynchronous component API and the new suspend component.

When users access the application, they do not need to load some parts of the UI immediately, such as dynamic UI functions such as modal boxes and tooltips. In addition, if we are using a single page application architecture, pages whose content is invisible on the page should not be loaded until needed.

Examples

In this example application, our application shows a ChatWindow component that will be loaded if the user is authenticated.

We assume that authentication can only be determined at run time and that the component is large. For these reasons, we need to load it lazily.

<template>
  <h3>Chat with friends here</h3>
  <chat-window v-if="auth" />
</template>
<script>
import ChatWindow from "@/components/ChatWindow";

export default {
  components: {
    ChatWindow
  },
  ...
}
</script>

Lazy loading using Vue3 asynchronous component API

Vue 3 introduces the defineAsyncComponent API, so it is very simple to implement lazy loading components.

defineAsyncComponent can accept a factory function that returns promise. Promise's resolve callback should be called after the server returns the component definition. You can also call reject(reason) to indicate that the load failed.

<script>
import { defineAsyncComponent } from "vue";

const ChatWindow = defineAsyncComponent(
  () => import("@/components/ChatWindow")
);

export default {
  components: {
    ChatWindow
  },
  ...
}
</script>

After construction, any dynamically imported components will be treated as a separate file.

File                                 Size

dist/js/chunk-vendors.f11402df.js    82.39 KiB
dist/js/app.ada103fb.js              20.59 KiB
dist/js/ChatWindow.3c1708e4.js       5.47 KiB
dist/css/app.8221c481.css            1.76 KiB
dist/css/ChatWindow.f16731cd.css     2.75 KiB

Loading state content

The disadvantage of lazy loading is that it requires team communication, and the rendering is uneven due to multiple requests. One way to deal with this problem is to display the loading state component when loading the component.

When a component is loaded, as shown in the following figure, a component is displayed after loading.

defineAsyncComponent can accept an object: it has a loadingComponent attribute, which indicates the component to be used when loading asynchronous components.

<script>
import { defineAsyncComponent } from "vue";
import Spinner from "@/components/Spinner.vue";

const ChatWindow = defineAsyncComponent({
  loader: () => import("@/components/ChatWindow"),
  loadingComponent: Spinner
});

export default {
  components: {
    ChatWindow
  },
  ...
}
</script>

Use with suspend

The above method of using loading state works well, but there are some limitations. For example, we may want to pass the prop to the loading state component, the content to its slot, etc., but it is not easy to implement using the asynchronous component API.

To increase flexibility, we can use the new suspend component in Vue3. This enables us to use slots to determine the asynchronous loading of content at the template level.

Suspend is a global component (such as transition) that can be used anywhere in a Vue 3 application. To use it, you need to declare it in the template and include two named slots: default and fallback.

Suspend ensures that the default slot is displayed when asynchronous content is loaded and uses the fallback slot as the loading state.

<template>
  <Suspense>
    <template #default>
      <h3>Chat with friends here</h3>
      <chat-window />
    </template>
    <template #fallback>
      <spinner color="blue" />
    </template>
  </Suspense>
</template>
<script>
import { defineAsyncComponent } from "vue";
import Spinner from "@/components/Spinner.vue";

const ChatWindow = defineAsyncComponent(
  () => import("@/components/ChatWindow")
);

export default {
  components: {
    ChatWindow,
    Spinner
  },
  ...
}
</script>

Asynchronous components are suspended by default. This means that if it has a < suspend > in the parent chain, it will be regarded as the asynchronous dependency of the < suspend >. In this case, the loading status will be controlled by < suspend >, and the loading, error, delay and timeout options of the component itself will be ignored.

Asynchronous components can choose to exit the suspend control, and can specify suspend: false in its options to let the component always control its loading state.

You can API reference See more options available.

~After that, I'm Xiao Zhi. I went to the SPA. See you next time!

The bugs that may exist after the code is deployed cannot be known in real time. Afterwards, in order to solve these bugs, we spent a lot of time on log debugging. By the way, we recommend a useful BUG monitoring tool Fundebug.

Original text: https://vuejsdevers.com/2020/...

communication

There are dreams and dry goods. Wechat search [Daqian world] pays attention to this dish washing wisdom who is still washing dishes in the early morning.

This article GitHub https://github.com/qq44924588... It has been included. There are complete test sites, materials and my series of articles for the interview of front-line large factories.

Keywords: Javascript Front-end Vue.js css

Added by brentech on Mon, 14 Feb 2022 02:31:39 +0200