Home > Web Front-end > Vue.js > Use asynchronous components in Vue projects to optimize performance

Use asynchronous components in Vue projects to optimize performance

青灯夜游
Release: 2020-09-28 17:33:29
forward
2586 people have browsed it

Use asynchronous components in Vue projects to optimize performance

When creating large applications using JavaScript frameworks, it is important to consider component structure. By considering the component structure, you can avoid loading each component at runtime and slowing down your application. When building your application, you can also avoid returning unnecessary data to the user or creating an overall poor user experience.

Frameworks such as React and Angular use React.lazy() and routing models respectively to consider the component structure.

In this article, we will implement two demos to see how Vue can use asynchronous components to reduce the loading time of the application by using lazy loading and code splitting techniques.

Creating Components in Vue

To understand how it works, let’s start by creating a basic component.

Navigate to your terminal, install Vue's CLI, and create a project:

npm install -g vue/cli
vue create book-project
#choose the default setting when prompted
Copy after login

In our new project folder, let's replace the contents of the default file, which includes helloworld.vue and app.vue. We'll start by creating a book donation page. Rename helloworld.vue to book.vue and replace its contents with the following:

<!--Book.vue-->
<template>
  <h1>Donate Books</h1>
</template>
Copy after login

Then, replace App with the following contents. Contents of vue:

<!--App.vue-->
<template>
  <div>
    <book></book>
  </div>
</template>

<script>
  Import Book from "./components/Book"
  export default {
    components: {
      Book
    }
  }
</script>

<style>
#app {
  font-family: &#39;Avenir&#39;, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>
Copy after login

In the above code block, you will notice that the Book component is statically imported. This means that the Book component is loaded every time the application is loaded.

Next, run npm run serve in the terminal, navigate to localhost:8080, and view your base components:

Use asynchronous components in Vue projects to optimize performance

Now, loading the Book component every time the application is loaded does not seem to be a significant performance issue. However, as the application gets larger, loading each component at runtime becomes cumbersome.

Your users won't interact with every feature in your app, so it makes sense to only provide the features they need. The question is, how do you load only what the user needs?

This is where lazy loading and code splitting techniques come into play. Lazy loading delays the initial loading of a component, preventing resources such as images from loading until the user navigates to their location on the page.

Code splitting is a feature originally provided by webpack. Webpack allows you to split your code into various packages that are only used when needed.

Vue performs code decomposition through a feature called dynamic imports.

This import uses webpack (or any module binder like Parcel) to load the component asynchronously. Its syntax consists of a promise, wrapped in an arrow function:

// dynamic import
import("./components/Book").then(Book => {
  // Insert the Book module here
});
Copy after login

Let’s implement this in our App.vue component:

<template>
  <div>
    <book></book>
  </div>
</template>

<script>
export default {
  components: {
    Book: () => import("./components/Book")
  }
};
</script>
Copy after login

In the code example above, The import() function returns the Book component, which allows us to load it asynchronously. If we look at the "Network" tab in the browser devtools, there is a file named 0.js initiated by App.js. This file contains our async component:

Use asynchronous components in Vue projects to optimize performance

Create a Vue application using async components

Let We continue building a basic book donation application to show how to take advantage of asynchronous components. Finally, we only want the Donate component to load when the user clicks the Donate button.

First, let's navigate to the terminal and install vue-material in our project folder. We will use this style for our application:

cd book-project
npm i vue-material
Copy after login

We will include vue-material in our application and import it in src/main.js:

import Vue from &#39;vue&#39;
import App from &#39;./App.vue&#39;
Vue.config.productionTip = false
import VueMaterial from &#39;vue-material&#39;
import &#39;vue-material/dist/vue-material.min.css&#39;
import &#39;vue-material/dist/theme/default.css&#39;
Vue.use(VueMaterial)
new Vue({
  render: h => h(App),
}).$mount(&#39;#app&#39;)
Copy after login

Now, let’s build the Book component we created earlier:

<!--Book.vue-->
    <template>
     <div id="app">
      <md-card md-with-hover v-for="(book, key) in books" v-bind:key="key">
          <md-ripple>
            <md-card-header>
              <div class="md-title">{{book.name}}</div>
              <div class="md-subhead">{{book.genre}}</div>
            </md-card-header>
            <md-card-actions>
        <md-button type="primary" @click="addBook(key)">Donate to improve {{book.genre}}</md-button>
            </md-card-actions>
          </md-ripple>
        </md-card>
        <div v-if="show">
          <md-card-content>
         <donate v-bind:selectList="selectList"></donate>
          </md-card-content>
    </div>
        <md-button @click="show = true" id="donate">Donate {{selectList.length}} book(s)</md-button>
      </div>  
    </template>
    
    <script>
      export default {
      name: &#39;RegularButtons&#39;,
      methods: {
        addBook (key) {
          if(!this.selectList.includes(key)) {
            this.selectList.push(key);
          }
        }
      },
      components: {
        donate: () => import(&#39;./Donate&#39;)
      },
      data: () => ({
        books: [
          { name: &#39;Using Creatine&#39;, genre: &#39;Workouts&#39; },
          { name: &#39;Learn Parkour&#39;, genre: &#39;Sports&#39; },
          { name: &#39;Snorkelling&#39;, genre: &#39;Diving&#39; },
        ],
        selectList: [],
        show: false
      })
    }
    </script>
Copy after login

In the above code block, the book list is retrieved from the books array and displayed. If the user clicks the button for each book, the addBook() method pushes the selected books into the selectList array and displays the total number of donated books.

There is also a separate button dedicated to loading asynchronous components. Its parameter show is set to true. This enables the v-if statement to display the donate component, which contains the number of selected books.

donate The component has been dynamically imported through the components attribute in the <script> tag.

Let's create the donate component. In the src/components folder, create a new file named Donate. And enter the following code example:

<template>
      <div title="Donate Books" key="donate">
          <p v-for="(x, y) in this.selectList" :key="y">
          Tip: {{books[Number(x)].name}} is about {{books[Number(x)].genre}}
          </p>
      </div>
</template>
<script>
export default {
  props: [&#39;selectList&#39;],
  data: () => ({
    books: [
      { name: &#39;Using Creatine&#39;, genre: &#39;Workouts&#39; },
      { name: &#39;Learn Parkour&#39;, genre: &#39;Sports&#39; },
      { name: &#39;Snorkelling&#39;, genre: &#39;Underwater&#39; },
    ]
  })
}
</script>
Copy after login

Navigate to your terminal and run npm run serve.

If the application compiles successfully, open localhost:8080 in the browser. The Donate component only loads when you click on the application while viewing the Network tab in Devtools, and when you click on the Donate button.

异步组件的错误处理

异步组件需要尽可能简单,以便快速加载。但是,在我们的异步组件中定义加载和错误组件有助于处理加载状态并在需要时显示错误消息。

In src/components, let&#39;s create two components: LoadingState.vue and ErrorState.vue:
Copy after login
<!--LoadingState.vue-->
    <template>
      <p><em>Loading...</em></p>
    </template>
Copy after login
<!--ErrorState.vue-->
    <template>
      <p>Could not display books. Kindly check your internet conection.</p>
    </template>
Copy after login

现在,在App.vue中,我们将导入两个组件并将它们添加到Book组件中:

<!--App.vue-->
<script>
import LoadingState from "./components/LoadingState"
import ErrorState from "./components/ErrorState"
const Book = import("./components/Book")
export default {
  components: {
    Book: () => ({
// Book is our default component
      component: Book,
// LoadingState is the component that is displayed while our default component
// is loading
      loading: LoadingState,
// ErrorState is the component that is displayed should our default component have an // error while loading
      error: ErrorState,
// A delay is set up before the loading component is shown
      delay: 100,
// Should this timeout be reached, the default component is considered to have failed // to load
      timeout: 2000
    })
  }
};
</script>
Copy after login

加载和错误状态不会出现,除非你有一个非常缓慢或错误的互联网连接。为了测试它们是否工作正常,我们将timeout属性设置为0,并尝试加载应用程序。

结论

使用异步组件构建大型应用程序是保持最佳性能的关键。异步组件不仅可以确保由于更快的加载时间,您的保留率会更高,而且还可以帮助您更有效地检测错误,因为组件的作用域是作为函数传递的。如果你想看看这个演示的源代码,你可以在GitHub上找到它。

相关推荐:

2020年前端vue面试题大汇总(附答案)

vue教程推荐:2020最新的5个vue.js视频教程精选

更多编程相关知识,请访问:编程入门!!

The above is the detailed content of Use asynchronous components in Vue projects to optimize performance. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:logrocket.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template