I saw an article before and it was written well. Here I will record my understanding.

This article addresses

Vue performance optimization has been done by itself, but it has not been listed systematically. It is recorded here for the convenience of future system optimization of new projects or new companies.

Vue code level optimization

This refers to the use of Vue syntax, which needs to be noted.

Flexible use of V-if and V-show

  • V-if determines whether elements will be rendered or not. It is not recommended if v-if conditions need to be toggled frequently, increasing the cost of rendering. It is suitable for conditions that do not toggle frequently, or for certain modules that may not need to be loaded
  • V-show determines whether or not an element is displayed, and elements are always rendered, just plain display: None /block style switching, suitable for places where conditions are frequently toggled

Have flexible use of computed and watch

  • Computed depends on other attribute values, and computed values are cached. Only when the dependent attribute values change, computed values will be recalculated the next time the computed values are obtained, which is suitable for complex condition judgment or numerical calculation to reduce the syntax complexity of templates
  • Watch monitors an action that I think is suitable for some general operations to be performed when attributes change, that is, WHEN XXX, I am yyY, a set of fixed processes, which means invoking methods, and computed means attributes more

V-for specifies the key. Do not use v-if or index as the key

  • V-for adds key values to improve the efficiency of diff and prevents the entire list from being re-compared
  • V-for has a higher priority than V-IF. If it is used at the same time, each element traversed will be judged once. If you need to display elements conditionally, you can use computed to filter out the elements that are not displayed and traverse again
  • Avoid using index as the key value. When inserting new elements or deleting an element in list, the index values of the elements following the element will be all changed, and the key value will be all changed. During diff, the virtual DOM corresponding to the key will be searched first, and it will be found that the key value is the same, but the virtual DOM is different. So there’s no key left

Long list performance optimization

You can use Object.freeze(obj) to freeze an Object if you simply want to display a lot of data without performing other operations. After freezing, data hijacking and modification cannot be performed.

Unlog the event and timer when the component is destroyed

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

Lazy loading of images

Common practice, mainly by scrollbar height and screen height to determine whether the current picture needs to be in the current view. The plug-in I use a lot here is vue-lazyLoad

npm install vue-lazyload --save-dev
import VueLazyload from 'vue-lazyload'
Vue.use(VueLazyload)
Vue.use(VueLazyload, {
    preLoad: 1.3.error: 'dist/error.png'.loading: 'dist/loading.gif'.attempt: 1
})
// Command
<img v-lazy="/static/img/1.png" alt="failed_pcture">
Copy the code

Route lazy loading

  • Without lazy loading, all routing components are compiled into the main package
  • Lazy route loading: the corresponding module is loaded only when the current route is entered. The initial loading is much faster and the module of the corresponding route is loaded without too much delay. Therefore, this method is recommended
const router = new VueRouter({
  routes: [{path: '/foo'.component: () = > import('./Foo.vue')}]})Copy the code

Tripartite libraries are introduced on demand

There may be some components in the tripartite library that we will never use. In the case of Element, if we only needed the Button component, there would be no need to introduce Element entirely:

/ / installation
npm install babel-plugin-component -D

/ / modify babelrc
{
  "presets": [["es2015", { "modules": false }]],
  "plugins": [["component",
      {
        "libraryName": "element-ui"."styleLibraryName": "theme-chalk"}}]]// in main.js
import Vue from 'vue';
import { Button } from 'element-ui';

 Vue.use(Button)
Copy the code

Basic component libraries provide on-demand functionality, and specific configuration methods are posted in the library documentation.

Infinite list optimization

Similar to lazy loading images, it also calculates scrollbar height and screen height to determine which data should be rendered. Data that is too far out of view can be directly not rendered. The corresponding three-party plug-in is vue-virtual-scroll-list vue-virtual-scroller

Server side rendering

SSR, the server will assemble all the data and send back an HTML that the browser can take and display.

  • The first screen loads faster without waiting for various Ajax requests
  • Better SEO conditions, Ajax is not friendly to crawlers, using SSR can be circumvented
  • The server will be under more pressure, and the development will also need to be in the Node Server running environment

Webpack packaging layer optimization

Small images using Base64 loading, Sprite, etc

The bottom line is to reduce HTTP requests

  • Static resource images that are a few kilobytes in size do not need to be requested from the server. You can use Webpack’s image-webpack-loader to convert them to Base64 format
  • Sprite image: Place multiple small ICONS in an image and use background-postion to determine which icon to display

Reduce redundant code from ES6 to ES5

Babel transforms ES6 code into ES5 code. This requires many helper functions. If multiple modules need these helper functions, they can be used only once.

/ / installation
npm install babel-plugin-transform-runtime --save-dev

// .babelrc
"plugins": [
    "transform-runtime"
]
Copy the code

Remove common code

If no processing is done:

  • The same resources are loaded repeatedly, wasting user traffic and server costs.
  • Too many resources need to be loaded on each page. As a result, the first screen of a web page loads slowly, affecting user experience.

This can be done using the CommonsChunkPlugin method built into Webpack:

// All packages that depend on package.json are packaged into vendor.js.
new webpack.optimize.CommonsChunkPlugin({
  name: 'vendor'.minChunks: function(module, count) {
    return (
      module.resource &&
      /\.js$/.test(module.resource) &&
      module.resource.indexOf(
        path.join(__dirname, '.. /node_modules'= = =))0); }}),// Extract the mapping of code modules
new webpack.optimize.CommonsChunkPlugin({
  name: 'manifest'.chunks: ['vendor']})Copy the code

Build package code analysis

Use the plugin: webpack-bundle-Analyzer

Some problems may be found after branching, such as a developer implementing a small feature that introduces a large library that would be difficult to find without code review, or some leftover useless code that is introduced but has no real purpose, like hidden deprecated code.

The simple configuration is as follows:

/ / webpack. Prod. Conf. Js
if (config.build.bundleAnalyzerReport) {
  const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
  webpackConfig.plugins.push(new BundleAnalyzerPlugin())
}
Copy the code

Remove third-party dependencies

A typical Vue project would have several dependency libraries: Vue, VUe-Router, Vuex, Axios, Element, Echart, LoDash. These libraries are packaged into the main package. The main package is usually several megs long, and the first load will be extremely slow.

  • Using the browser to make multiple requests at the same time, using it to slim the main package,Six 1MB files will download faster than one 6mb file, the first loading speed will be significantly improved after pulling away
  • Dependent libraries do not change very often, or are generally not modified, and caches are better utilized. Modifying business code does not refresh the cache of these files

We introduced these tripartite libraries using external JS:

// webpack.prod.conf.js
// Library files use CDN
externals: {
    'vue': 'Vue'.'vuex': 'Vuex'.'vue-router': 'VueRouter'.'axios': 'axios'.'element-ui': 'ELEMENT'.// Element's umD file variable is named Element
    'echarts': 'echarts'.'lodash': '_',},// index.html -- Libraries that do not affect rendering can add defer for deferred download
<script src="cdn/vue.min.js"></script>
<script src="cdn/vuex.min.js"></script>
<script src="cdn/vue-router.min.js"></script>
<script src="cdn/axios.min.js"></script>
<script src="cdn/element/index.min.js"></script>
<script src="cdn/lodash.min.js" defer></script>
<script src="cdn/echarts.min.js" defer></script>
Copy the code

General optimization tips

GZIP is enabled on the server

If your web page is 30K, you can compress it to 9K. You can see it in the response header in the browser:

Use caching wisely

Reasonably set the cache expiration time and file ETag, modify the code after the version number detection modification. Data can even be cached on the front screen, and interface information can also be cached on the browser side.

Use the CDN

CDN has better availability, lower network latency and packet loss rate. Static resources can be put in. CDN domain names should not be too many. 2-3 CDN domain names are appropriate to better use DNS cache and reduce the cost of DNS resolution.

Reduce the use of global variables

  • In Chrome’s case, global variables are not well marked, and the browser can’t determine when to do garbage collection.
  • Global variable contamination.

Reducing DOM hierarchy

Too many DOM layers increase the cost of rendering, and the cost of diff for the virtual DOM

Rearrangement (reflux) and redraw problems

Considerations for loading and updating views, for animating, for writing alternative tags (IMG, etc.) and for causing rearrangements

Avoid USING CSS expressions

Calculation is slow and performance consuming