I haven't written a blog post for a long time. This article is a summary of my experience of using the vue framework for half a year. It is just a matter of content. This article only applies to projects initialized by vue-cli or projects that rely on webpack packaging.
A few days ago, I saw everyone saying that the bigger the vue project, the harder it is to optimize, which brings a lot of pain, which is inevitable. The problem must be solved in the end. There is no problem with the performance of the framework, and major test websites have relevant data. Go to the main topic below
Basic optimization
The so-called basic optimization is something that any web project needs to do and is the source of the problem. HTML, CSS, and JS are the first steps to optimize
Corresponding to the .vue file,<template>,<style>,<script>,
Let’s talk about the points worth optimizing in the vue project one by one
template
I won’t talk about semantic labels, avoiding random nesting, reasonably naming attributes and other standard recommendations.
The template part helps us display structured data. Vue drives the view through data. Please pay attention to some points.
- v-show, which one is used for v-if? In my opinion, we need to think about the problem in two dimensions. The first dimension is the permission issue. As long as the permission-related display is involved, we must use v-if. The second dimension is selected based on the frequency of user clicks without permission restrictions. Use v-show frequently and use v-if infrequently. The optimization point here is to reduce the total number of doms in the page. I prefer to use v-if because the number of doms is reduced and the first-screen rendering is accelerated. As for performance, I feel that the rendering process of switching will not affect the user's experience.
- Don't write too many expressions and judgments in the template
v-if="isShow && isAdmin && (a || b)",
Although this expression can be recognized, it is not a long-term solution. When you feel uncomfortable, write it appropriately into methods and computered to encapsulate it into one method. This advantage is that it is convenient for us to judge the same expression in multiple places, and call the same method when other elements with the same permissions are judged and displayed. - Add a key when calling a child component on a loop. The key can uniquely identify a loop individual. You can use, for example, as a key, if the array data is like this
['a' , 'b', 'c', 'a'],
use:key="item"
Obviously it doesn't make sense, the better way is to loop(item, index) in arr, then :key="index"
to ensure the uniqueness of the key.
style
- Put the style file inside or outside the vue file? There is no point in discussing it. The key is to divide it by module. My habit is to put it inside the vue file. It is convenient to write code. It is to jump up and down in the same file. It is recommended to add it regardless of internal and external.
<style scopeed>
Locking style files is very simple. No matter how easy it is to use, it cannot avoid the trouble of multiple people's development. The agreed naming rules may also conflict. After locking the area, try to use short naming rules as much as possible..header-title__text
Classes like this can be handled directly by .title. - In order to distinguish it from the previous article, let’s talk about the global style file and the global style file, try to abstract it as much as possible. Since it is not repeated in each component, try to be general. The better the abstraction of this part means that the smaller the size of your style file and the higher the reuse rate. It is recommended to put code that rewrites component libraries such as Element styles into the global world.
- I don't use float layout. I saw many people encapsulating it before
.fl -- float: left
Go to the global file, and then you need .clear. The current browser is not as weak as you have to use float to be compatible. It is completely flex. Grid compatibility is average. In fact, the flex layout can be implemented. float will cause trouble in layout. Anyone who has used it knows that it doesn’t believe it.
As for other common specifications, I will not go into details here, there are many related articles.
script
This part is also the most difficult point to optimize. Let me give you my personal opinion.
- Try to keep each component as much as possible when developing multiple people
export default {}
The order of methods within is consistent, making it convenient to find the corresponding methods. I am personally used to data, props, hooks, watch, computed, components. - What you want to say in data is to initialize the structure of the data as detailed as possible, with clear naming, simple and easy to understand, and avoid useless variables. isEditing can actually represent two states, true or false. Don't define notEditing to control the display, it can be completely in the template.
{{ isEditing? Editing: Save }}
- When passing values by parent and child components, try to :width="" :heigth="" Don't :option={}. The advantage of refinement is that only parameters that need to be modified are passed, data types are added to the child component props, whether they must be passed, and the default value is to facilitate troubleshooting errors and make the value transmission more rigorous.
- Just understand the meaning of the life cycle, what time should be requested, what time should be cancelled, and which methods need to be cancelled. Simple and easy to understand, and it is written on the official website.
- Each method in methods must be simple, do only one thing, try to encapsulate a reusable short method, and do not easily have too many parameters. If you rely heavily on lodash development, methed will look much simpler, and the cost is that the overall bundle will be larger. If the project only uses a small number of methods, you can introduce loadsh locally. If you don't want to use lodash, you can encapsulate a file yourself.
- Which problem to use watch or computered is found on the official website. The calculation attribute is mainly to do a filter conversion. Do not add some call methods to it. The function of watch is to listen to data changes to change data or trigger events such as
this.$('update', { ... })
Component optimization
The componentization of vue is very popular. The degree to which the component is disassembled is reasonable, and it varies depending on the size of the project. Small projects can be simple for several components, even without vuex, axios, etc. If the scale is large, you need to subdivide the components. The thinner the better, including the layout packaging, buttons, forms, prompt boxes, carousels, etc. It is recommended to look at the code of the Element component library. If you don’t have time to write such details, you can use the Element library directly to optimize it in several points.
- Components have clear meanings and only deal with similar businesses. The higher the reusability, the better, and the stronger the configuration, the better.
- Encapsulate components yourself or follow the rules of configuring props.
- I habitually divide the component classification into three categories, page, page-item and layout. Page is the routing control part, page-item belongs to various layout blocks in the page such as banner, side, etc., and components that place multiple pages in the layout appear at least twice, such as icon, scrollTop, etc.
vue-router and vuex optimizations
In addition to switching routes, vue-router uses the most logic of processing permissions. I will not elaborate on the control of permissions here. There are many related demos and articles. When it comes to optimization, it is worth mentioning.Lazy component loading
The official website link at noon is as follows, the examples are as follows
const Foo = r => ([], () => r(require('./')), 'group-foo') const Bar = r => ([], () => r(require('./')), 'group-foo') const Baz = r => ([], () => r(require('./')), 'group-foo')
This code packages the three components Foo, Bar, and Baz into a chunk file called group-foo, of course, it is a js file
The rest of the parts can be written normally. When the website loads, it will automatically parse which chunk needs to be loaded. Although the total volume of the package will increase, it will be much faster if you just look at the requested first screen speed.
There are several problems and solutions facing vuex
When the website is large enough, there are many fields in the root under a state tree. To solve this problem, you need to modularize vuex. The official website provides a modular solution that allows us to configure modules when initializing vuex. Each module contains state, action, etc., which seems to be multiple state trees, but in fact it is still a subtree based on rootState. After subdividing, the entire state structure becomes clear and it is much easier to manage.
Due to the flexibility of vuex, there is a situation where coding is not unified. The complete closed loop is ('action') -> action -> commit -> mutation -> getter -> computed. In fact, some intermediate links can be omitted, because the API document provides the following methods mapState, mapGetters, mapActions, mapMutations, and then you can directly call any step in the component, or you can call it in a small project. When the project is large, you must consider the unity of vuex usage. My suggestion is to run a complete closed loop no matter how simple the process is, to form a unified code, which is convenient for post-management. Only dispatch and mapGetters are allowed in my component, and the rest of the processes are carried out in the vuex folder named store.
Based on the above article, let’s talk about what to do in each process. There must be inconsistencies in the front and back end data, either data structures, or field naming. So where should we handle the logic of data conversion? Some people will say that any step can be achieved, but it is not the case. My suggestions are as follows
- Before issuing dispatch, handle the data structure and field names of parameters that need to be passed in the component.
- Action allows us to do a lot of things, because this movie supports asynchronousness, supports state, rootState, commit, dispatch, getters, which shows that the responsibility is heavy. First, if the backend needs some data in other modules, it must be used to obtain the value through rootState and then integrate it into the original data. The next step is to issue a request. It is recommended (async await + axios), filter and convert after obtaining the data, and then send commit to mutation.
- This step is to update the converted data to the state. There may be a data distribution process (passing into an object to change the value of the key in multiple states). You can convert the data structure, but try not to convert the field. In the previous step,
- At this time, the store has been updated. Use the getter method to get the value. Token: state => , try not to convert the data only. The point that needs to be converted is that the same field is used in multiple places, but the structure is different (it rarely occurs).
- Use mapGetters in the component to get the corresponding getter value.
Packaging optimization
The above talks about the specifications and optimizations in terms of code, and the following are the key packaging optimizations. The vendor bundle that was packaged some time ago was 1.4M, and the app bundle also had 270K. The app bundle can be solved by lazy loading of components. How to solve the vendor package?
Some people may question whether there is no compression or the dependency package is not deduplicated. In fact, it is just 1.4M that I saw.
The solution is very simple. When packaging vendor, it does not package vue, vuex, vue-router, axios, etc., and uses domestic bootcdn to directly introduce it into the root directory.
For example:
<script src="///vue/2.2.5/"></script> <script src="///vue-router/2.3.0/"></script> <script src="///vuex/2.2.1/"></script> <script src="///axios/0.15.3/"></script>
There is an externals in webpack that can ignore libraries that do not need to be packaged
externals: { 'vue': 'Vue', 'vue-router': 'VueRouter', 'vuex': 'Vuex', 'axios': 'axios' }
The vendor package at this time will be very small. If it is not small enough, you can split other libraries. The number of requests is increased at this time, but it is much faster than loading a 1.4M bundle.
Summarize
The optimization discussed in this article can solve some performance problems, and there are many actual development details. In short, writing code according to the specifications, the team's coding style should be as unified as possible, and thinking more about the details can be solved.
The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.