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
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>
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: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
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:
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 });
Let’s implement this in our App.vue component:
<template> <div> <book></book> </div> </template> <script> export default { components: { Book: () => import("./components/Book") } }; </script>
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:
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
We will include vue-material
in our application and import it in src/main.js
:
import Vue from 'vue' import App from './App.vue' Vue.config.productionTip = false import VueMaterial from 'vue-material' import 'vue-material/dist/vue-material.min.css' import 'vue-material/dist/theme/default.css' Vue.use(VueMaterial) new Vue({ render: h => h(App), }).$mount('#app')
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: 'RegularButtons', methods: { addBook (key) { if(!this.selectList.includes(key)) { this.selectList.push(key); } } }, components: { donate: () => import('./Donate') }, data: () => ({ books: [ { name: 'Using Creatine', genre: 'Workouts' }, { name: 'Learn Parkour', genre: 'Sports' }, { name: 'Snorkelling', genre: 'Diving' }, ], selectList: [], show: false }) } </script>
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: ['selectList'], data: () => ({ books: [ { name: 'Using Creatine', genre: 'Workouts' }, { name: 'Learn Parkour', genre: 'Sports' }, { name: 'Snorkelling', genre: 'Underwater' }, ] }) } </script>
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's create two components: LoadingState.vue and ErrorState.vue:
<!--LoadingState.vue--> <template> <p><em>Loading...</em></p> </template>
<!--ErrorState.vue--> <template> <p>Could not display books. Kindly check your internet conection.</p> </template>
现在,在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>
加载和错误状态不会出现,除非你有一个非常缓慢或错误的互联网连接。为了测试它们是否工作正常,我们将timeout属性设置为0,并尝试加载应用程序。
结论
使用异步组件构建大型应用程序是保持最佳性能的关键。异步组件不仅可以确保由于更快的加载时间,您的保留率会更高,而且还可以帮助您更有效地检测错误,因为组件的作用域是作为函数传递的。如果你想看看这个演示的源代码,你可以在GitHub上找到它。
相关推荐:
更多编程相关知识,请访问:编程入门!!
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!