First published on GitHib: github.com/SimonZhangI…

Runtime optimization

1. Use v-if instead of v-show

The difference between the two is that v-if does not render the DOM, whereas V-show prerenders the DOM

Use v-if in all cases except v-show

  • There are pre-rendering requirements

  • You need to change the display status frequently

2. V-for must have a key, and avoid using v-if at the same time

We tend to do this in two common situations:

  • To filter items in a list such as V-for =”user in users” v-if=” user.isactive “. In this case, replace Users with a calculated property (such as activeUsers) and have it return the filtered list

  • To avoid rendering lists that should be hidden like v-for=”user in users” v-if=”shouldShowUsers”. In this case, move v-if to the container element (e.g. Ul, OL)

3. The event is destroyed in time

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.

We need to manually remove the listener for these events during component destruction to avoid memory leaks. For example:

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

The first screen to optimize

1, picture cutting, use webP

  • The picture needs to be cropped, usually using a double figure

  • Use WebP images whenever possible

  • If vue-lazyload is used, you can replace webP with one click (replacing images using v-lazy)

Vue.use(VueLazyload, {
  error: require('./assets/img/defaultpic_small.png'),
  filter: {
    webp (listener: any, options: any) {
      if(! options.supportWebp)return
      // listener.src += '.webp'}}});Copy the code

2. Advance resource requests

After testing, the loading sequence of files in Vue project is router.js, main.js, app.vue, [Page].vue, [Component].vue, as shown in the figure:

The loading time of router is nearly 100ms faster than that of page.vue. If there are many files in Page. vue, the time difference will be even bigger. Therefore, interface data can be requested when the page is mounted and rendered, for example, in router.js:

import Router from 'vue-router'
import store from './store'

store.dispatch('initAjax')
Copy the code

3. Asynchronous routes

Asynchronous routing can automatically load the required page resources according to the URL, and does not cause page blocking. It is suitable for mobile pages

You are advised to import the home page directly and use asynchronous routes for non-home pages

Usage:

{
  path: '/order'.component: (a)= > import('./views/order.vue')}Copy the code

4. Asynchronous components

Components that do not need to be loaded on the first screen are loaded in the way of asynchronous components (such as multiple tabs), including actions that need to trigger conditions are also loaded in the way of asynchronous components (such as popovers) : V-if is used to control the display timing, and Promise of the component is introduced

<template> <div> <HellowWorld v-if="showHello" /> </div> </template> <script> export default { components: { HellowWorld: () => import('.. /components/HelloWorld.vue') }, data() { return { showHello: false } }, methods: { initAsync() { addEventListener('scroll', (e) => { if (scrollY > 100) { this.showHello = true } }) } } } </script>Copy the code

5. Use lightweight plug-ins, asynchronous plug-ins

  • Use webpack-bundle-Analyzer to look at the size of all the packages in your project, with larger plug-in packages looking for lightweight alternatives

  • Use asynchronous loading of plug-ins that are not used on the first screen or are only used in certain scenarios (e.g. location plug-ins, in some cases latitude and longitude can be passed through urls; Or generate pictorial plug-ins that need to be triggered when clicked); After the plug-in is loaded for the first time, it is cached locally in the following ways:

// Take positioning plug-ins as an example
const latitude = getUrlParam('latitude')
const longitude = getUrlParam('longitude')
// If there is no latitude and longitude parameter, use the positioning plug-in to obtain the latitude and longitude
if(! latitude || ! longitude) {// The positioning plug-in is loaded for the first time
  // await import('locationPlugin') with webpack3 or below
  if (!this.WhereAmI) this.WhereAmI = (await import('locationPlugin')).default
  // do sth...
}
Copy the code

6. Public CDN

Using common CDN resources can play a caching role and reduce packaging volume

Network optimization

1. Reduce network requests

The browser limits the number of requests for the same domain name at the same time (usually six). If the number exceeds the limit, the requests will be blocked

The first screen minimizes requests for the same domain name, including interfaces and JS; Reduce chunk.js on the first screen as needed and merge interface requests

2. Properly use preload, dns-prefetch, and preFETCH

  • Preload has a high load priority and can preload resources using gap time, separating loading from execution and not blocking onload events for rendering and document

  • DNS resolution is required for each connection to a domain name. Using dns-prefetch, the DNS of a domain name can be preresolved

  • Prefetch preloads resources that may be used by the page in the future, with a lower priority. It is not recommended for projects requiring high first screen rendering

The three usage modes are added in the head TAB (vue-CLI-3 has been configured accordingly) :

<head>
  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width,initial-scale=1" />
  <link rel="icon" href="/dist/favicon.ico" />
  <! -- dns-prefetch -->
  <link rel="dns-prefetch" href="//www.dpfile.com" />
  <title>md-config</title>
  <! -- preload, as attribute must -->
  <link href="/dist/css/app.52dd885e.css" rel="preload" as="style" />
  <link href="/dist/js/app.05faf3b5.js" rel="preload" as="script" />
  <link href="/dist/js/chunk-vendors.04343b1f.js" rel="preload" as="script" />
  <! -- prefetch -->
  <link href="/dist/js/chunk-vendors.04343b1f.js" rel="prefetch" />
</head>
Copy the code

3, PWA

PWA supports caching of HTML documents, interfaces (GET), and so on, reducing the time of page white screen so that pages can be displayed quickly even in weak network or down network conditions

Compile and package optimization

1. Upgrade VUE-CLI-3

Vue-cli-3 uses WebPack4 +babel7, many optimizations for compilation and packaging (multiple improvements), uses YARN as a package management tool, and defaults to many optimizations’ best practices

After the project is migrated from VUE-CLI-2 to VUe-CLI-3, the speed changes are as follows:

Compilation time: 44s –> 7s Packaging time: 55s –> 11s

The efficiency gains are significant

2, SSR

You are advised to upgrade SSR for items that have high load performance requirements