V-if and V-show are used in different scenarios

V-if is true conditional rendering because it ensures that event listeners and subcomponents within the conditional block are properly destroyed and rebuilt during the switch; Also lazy: if the condition is false during the initial render, nothing is done — the conditional block does not start rendering until the condition is true for the first time.

  • True: Render elements
  • False: Remove elements without rendering

V-show is much simpler. Regardless of the initial conditions, elements are always rendered and simply switched based on the display property of CSS.

  • True: display: block
  • False: display: none

Therefore, V-IF is suitable for scenarios where conditions are rarely changed at runtime and do not need to be switched frequently; V-show is suitable for scenarios that require very frequent switching of conditions.

Use more computed attributes computed

Computed: Computed attributes depend on other attribute values, and computed values are cached. Only when the dependent attribute values change, computed values will be recalculated the next time it obtains computed values. When we need to do numerical calculations and rely on other data, we should use computed instead of Watch, because we can take advantage of the caching nature of computed and avoid recalculating every time we get a value. You can think of computed properties as data that can handle logic.

export default {
  data() {
    return {
      actualPrice: 10.// Actual price
      sellingPrice: 20.// Sales price
      profit: 0, profit}},watch: {
    actualPrice: {
      handler(val) {
        this.profit = this.sellingPrice - this.actualPrice
      },
      immediate: true,},sellingPrice: {
      handler(val) {
        this.profit = this.sellingPrice - this.actualPrice
      },
      immediate: true,}}}Copy the code

If you use watch to process this logic, it is not only troublesome and not very good performance. If you use computed data, it is very convenient. Moreover, computed data can cache the results, and if your dependency value does not change, the logic operation will not be triggered

export default {
  data() {
    return {
      actualPrice: 10.// Actual price
      sellingPrice: 20.// Sales price}},computed: {
    profit() {
      return this.sellingPrice - this.actualPrice
    }
  },
}
Copy the code

V-for traversal avoids using v-if simultaneously

V-for has a higher priority than V-if, so when two instructions appear in a DOM, the current list rendered by V-FOR needs a V-IF judgment each time. The corresponding list will also change, which seems very unreasonable. So when you need to do a synchronization command. Use calculated attributes whenever possible, and filter out values that are not needed by V-if. He looks something like this.

// Calculate attributes
computed: {
  filterList() {
    return this.showData.filter((data) = > {
      return data.isShow
    })
  }
}
  
// DOM
  
<ul>
  <li v-for="item in filterList" :key="item.id">
  {{ item.name }}
  </li>
</ul>
Copy the code

V-for traversals must add a key to the item and avoid using index as an identifier

During the traversal rendering of list data, a unique key value should be set for each item to facilitate the accurate finding of the list data by vue.js internal mechanism. When state is updated, the new state value is compared to the old state value to locate the DIFF faster. In addition, vFor does not recommend using index as the key value. This is a very easy to understand knowledge point. As can be seen from the figure, when index is used as the identifier, the key behind it in the list changes when inserting a piece of data. The current VFS all re-render elements with key changes, but they don’t change anything except the Element data they insert, resulting in unnecessary overhead. Instead of using index as an identifier, use unique values in the data, such as id fields.

Long list performance optimization

Vue hijacks data via Object.defineProperty to make the view respond to data changes. However, sometimes our component is purely a data presentation and nothing will change. We don’t need Vue to hijack our data. This significantly reduces component initialization time, so how do we prevent Vue from hijacking our data? Freeze can be used to freeze an Object. Once the Object is frozen, it cannot be modified.

export default {
  data () {
    return {
      users: {}}}.async created () {
    const users = await axios.get('/api/users')
    this.users = Object.freeze(users)
  }
}
Copy the code

Optimize infinite list performance

In this project, there are a lot of long list scenarios, which are different from regular paging. Most of the front end when doing this kind of infinite list, most of the new front end is through a vFor to iterate through the data. Continue requesting the API while scrolling to the bottom. In fact, this is not properly thought out. As the data loading, DOM will be more and more, thus lead to the problem of performance overhead produced, when the DOM on the page too much, unavoidably create constant pressure to my client, so for a long list of rendering, proposed to the DOM remove, similar to the picture of lazy loading mode, only appeared on the view of the DOM DOM is important. There are some good solutions on the Internet. UI libraries such as ElementUI and Ant-Design have infinite scrolling components, such as vue-virtual-Scroller and Vue-virtual-Scroll list. You can choose rationally.

Other solutions can be found at github.com/vuejs/aweso…

Releasing component Resources

When a Vue component is destroyed, it automatically cleans up its connections to other instances and unties all its instructions and event listeners, but only for the component’s own events. If you use addEventListene or other methods in JS, they will not be automatically destroyed. We need to manually remove the listening of these events when the component is destroyed to avoid memory leaks, such as:

created() {
  addEventListener('click'.this.click, false)},beforeDestroy() {
  removeEventListener('click'.this.click, false)}Copy the code

Or timers:

created() {
  this.currentInterVal = setInterval(code, millisec, lang)
},
beforeDestroy() {
  clearInterval(this.currentInterVal)
}
Copy the code

Image resource optimization

In web pages, there are often a large number of image resources, these resources are large or small. When we have a large number of images in the DOM on a page, we are not likely to encounter some problems with slow loading, or even load failures.

  • Use SVG or font ICONS for small ICONS, or make Sprite images
  • Load small images through Base64 and WebP
  • Use CDN for large drawings that can be accelerated by CDN
  • Lazy loading of image resources
  • Compress image size
    • For static images, use a unified tool to compress them
    • Use tools such as Tinypng
    • Note: It is not recommended to build compressed images with Webpack.
    • If it is a dynamic image, such as an image in a user-created article, this is definitely recommended for the back end to compress. Modern back ends rarely handle image compression themselves, and most of them use paid cloud services.

Route lazy loading

Vue is a single-page application, which may have a lot of routes introduced. In this way, the files packaged with WebPCAk are very large. When entering the home page, too many resources are loaded, and the page will appear white screen, which is not conducive to user experience. It would be much more efficient if we could split the components corresponding to different routes into different code blocks and then load the components only when the routes are accessed. This will greatly speed up the first screen, but may slow down the rest of the page.

/ / the require syntax
component: resolve= >(require(['@/components/HelloWorld'],resolve))

/ / import syntax
component: () = > import('@/components/HelloWorld')
Copy the code

Note: route lazy loading is asynchronous components, not too many asynchronous components, otherwise there will be packaging performance problems. A word of caution: you don’t have to route to use asynchronous components; you can use asynchronous components in normal components.

On-demand introduction of third-party component libraries

Make sure that when using UI frameworks such as Element, And Design, you use the official exposed on-demand components. The components of the current UI framework are loaded only when they are actually used, rather than loading the entire library of components in the first place. As we all know, a UI framework is quite large compared to other things. Therefore, it is convenient for us developers at the same time, but also virtually generated redundant overhead. But you have to rely on it during the project lifecycle. Therefore, it is recommended to use on-demand loading as much as possible. Reasonable to the project to stop loss, if you do not care, very troublesome, then you can carry out the overall introduction.

Optimized first screen rendering

  • Route lazy loading
  • Add loading animation and skeleton screen on the home page
  • Pre-render, where pages with no dynamic data are pre-rendered to static pages
  • Extreme solution: Server-side rendering, if only because the first screen rendering is slow, actually not recommended to introduce server-side rendering, because the cost is relatively high, unless you want to solve SEO, the fact that you have to do server-side rendering.

Do not pack third-party packages

The Vue CLI configuration file tells Webpack to look for these third-party packages globally when they are loaded, rather than compile and load them.

const isProd = process.env.NODE_ENV === 'production'

const cdn = {
  externals: {
    'element-ui': 'ELEMENT'.vue: 'Vue'.moment: 'moment'
  },
  js: [
    'https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js'.'https://cdn.jsdelivr.net/npm/[email protected]/lib/index.min.js'.'https://cdn.jsdelivr.net/npm/[email protected]/moment.min.js'].css: [
    'https://cdn.jsdelivr.net/npm/[email protected]/lib/theme-chalk/index.css']}const config = {
  ...

  chainWebpack: config= > {
    if (isProd) {
      config.plugin('html').tap(args= > {
        args[0].cdn = cdn
        return args
      })
    }
  },

  configureWebpack: {}}if (isProd) {
  config.configureWebpack.externals = cdn.externals
}

module.exports = config
Copy the code

About externals configuration reference here: in webpack webpack.js.org/configurati…

Import CDN resource links for third-party packages you want to compile in the index.html file:

<! DOCTYPEhtml>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <title><%= htmlWebpackPlugin.options.title %></title>
    <% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.css) { %>
      <link rel="stylesheet" href="<%= htmlWebpackPlugin.options.cdn.css[i] %>">The < %} % ></head>
  <body>
    <noscript>
      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <div id="app"></div>
    <script src="/aliyun-upload-sdk/lib/es6-promise.min.js"></script>
    <script src="/ aliyun - upload - SDK/lib/aliyun oss - SDK - 5.3.1. Min. Js." "></script>
    <script src="/ aliyun - upload - SDK/aliyun - upload - SDK - 1.5.0. Min. Js." "></script>
    <% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.js) { %>
      <script src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script>The < %} % ></body>
</html>
Copy the code

It’s important to note that although you don’t need to use third-party packages in node_modules, it’s best to keep package dependencies in package.json. The reasons for keeping it are twofold:

  • More explicit dependency information
  • TypeScript requires type declaration information in packages

It is also not recommended to unpack all third parties, as this will result in too many requests and slow loading.

Transport layer optimization

To further speed up resource requests, you can enable THE GIZP compression function on the server. Most browsers support GZIP. You can enable the GZIP function on the server to compress resources before transferring them. Gzip is supported if the following information is displayed in the network Request:

Accept-Encoding: gzip, deflate, br
Copy the code

HTTP cache

Reference: developer.mozilla.org/zh-CN/docs/…

Ok, so there are some optimization strategies that you can use in your Vue project, some of which are a little sketchy, but you can use this post as a guide and delve into the details yourself as you develop.