Performance optimization of Vue project

Master of Wannian Da Ye Yi 2020-11-12 17:27:06
performance optimization vue project


Made quite a few vue project , There are also many problems in the development process , To sum up ,

Vue The code level

1、v-for Traversal should be item add to key, And avoid simultaneous use v-if

(1) The official recommendation v-for Traversal should be item add to key attribute

When the list data is traversed and rendered , Need for each item item Set up the only key value , convenient Vue.js Internal mechanism accurately finds the list data . When state update , Compare the new state value with the old one , Quickly navigate to diff .

(2) Official statement v-for Traversal avoid using at the same time v-if

v-for Than v-if High priority , If you have to traverse the entire array every time , Because of the intermediate calculation, the contrast will affect the rendering speed , Especially when it needs to render a small part of it , If necessary, it can be replaced with computed attribute .

recommend :

<ul>
<li
v-for="book in books"
:key="book.id">
{{ book.name }}
</li>
</ul>
computed: {
activeBooks: function () {
return this.books.filter(function (book) {
return book.isActive
})
}
}

Not recommended :

<ul>
<li
v-for="book in books"
v-if="book.isActive"
:key="book.id">
{{ book.name }}
</li>
</ul>

Be careful : If you have to use it, you can use template Wrap it up

<ul>
<template v-for="book in books" :key="book.id">
<li v-if="book.isActive">
{{ book.name }}
</li>
</template>
</ul>

2、computed and watch

computed: It's computational properties , Depend on other property values , also computed The value of has cache , Only the property value it depends on changes , Next acquisition computed Will be recalculated computed Value
  • When we need to do numerical calculations , And depend on other data , You should use computed, Because it can be used computed Cache properties for , Avoid every time you get a value , All have to be recalculated . For example, in the form operation , When the input or selection value changes , Other values are changed in linkage .
watch: Is more of a 「 Observe 」 The role of , Similar to some data monitoring callbacks , Whenever the monitored data changes, a callback will be executed for subsequent operations
  • When we need to perform asynchronous or expensive operations when data changes , You should use watch, Use watch Option allows us to perform asynchronous operations ( Visit one API ), Limit how often we do this , And before we get the final result , Set intermediate state . These are all things that computational properties can't do .

3、v-if and v-show

v-if  yes   real   Conditional rendering , Because it ensures that the event listeners and child components within the condition block are properly destroyed and rebuilt during the switch ; It's also The inertia of the : If the condition is false at the initial render , And do nothing —— Until the condition is true for the first time , Before the condition block is rendered .

v-show  It's much simpler , Whatever the initial conditions are , Elements are always rendered , And simply based on CSS Of display Property to switch .

therefore ,v-if It is applicable to conditions that are rarely changed during operation , Scenes that do not need to switch conditions frequently ;v-show It is suitable for scenarios that require very frequent switching conditions , such as tabs Component switching .

4、 Long list performance optimization

Vue Will pass Object.defineProperty Hijack data , To implement the view response to data changes , However, sometimes our components are pure data presentation , There will be no change , We don't need it Vue To hijack our data , In the case of a large amount of data , This can significantly reduce the time of component initialization , Then how to prohibit Vue Hijacking our data ? Can pass Object.freeze Method to freeze an object , Once frozen objects can no longer be modified .

export default {
data: () => ({
books: []
}),
async created() {
const books = await axios.get("/api/books");
this.books = Object.freeze(books);
}
};

5、 Optimize infinite list performance

If your app has a very long or infinite scrolling list , So we need to adopt “ Windowing ” Technology to optimize performance , Only a few areas need to be rendered , Reduce re rendering of components and creation dom Node time .window.requestAnimationFrame Method to set the function of delayed loading Click to see an example
Or you can refer to vue-virtual-scroll-list and vue-virtual-scroller Project approach ,
Or, for example ElementUI, In this way UI The frame has a separate infinite scrolling list component

6、 Global events are manually destroyed , Avoid memory leaks

We are .vue The event of file registration will be in vue Components are automatically removed when they are destroyed ,. But if <script> The global event definition method is used in the tag window.addEventListener To register Events , Consider possible memory leaks , So it is recommended that .vue Manually delete files when they are logged out

beforeDestroy() {
removeEventListener('click', this.handleClick, false)
}

7、 Lazy loading of picture resources

For pages with too many pictures , To speed up page loading , So a lot of times we need to not load the pictures that do not appear in the visual area in the page first , Wait until you scroll to the visible area before loading . This will greatly improve the page loading performance , It also improves the user experience . Used in projects Vue Of vue-lazyload plug-in unit :

(1) Installing a plug-in

npm install vue-lazyload --save-dev;

(2) At the entrance file man.js To introduce and use

import VueLazyload from 'vue-lazyload';

stay vue Use in

Vue.use(VueLazyload);
// Or add custom options
Vue.use(VueLazyload, {
preLoad: 1.3,
error: 'dist/error.png',
loading: 'dist/loading.gif',
attempt: 1
});

(3) stay vue file img Labeled src Property is changed to v-lazy , In this way, the image display mode is changed to lazy loading display :

<img v-lazy="/static/img/1.png">

8、 Road load by lazy , Components are introduced on demand

Vue It's a single page app , There may be many routing entries , Use this way webpcak The packed file is big , When entering the home page , Too many resources loaded , There will be a white screen on the page , Bad for user experience . If we can divide the components corresponding to different routes into different code blocks , Then load the corresponding components when the route is accessed , It's more efficient . This will greatly improve the speed of the first screen , But maybe other pages will slow down .

Road load by lazy :

const Foo = () => import('./Foo.vue');
const router = new VueRouter({
routes: [
{ path: '/foo', component: Foo }
]
});

A kind of aided design , More flexible control of routing ( Black and white list mode ), Unified processing of files within the folder ,concat All routing information

const files = require.context('.', true, /\.js$/);
var subRouters = [];
files.keys().map((key) => {
if (key === './index.js') return;
// console.log(files(key).default);
subRouters = subRouters.concat(files(key).default);
});
export default subRouters;

9、 On demand introduction of third-party plug-ins

Very common configuration , For example, we think there are UI The component does not satisfy , To quote something else UI A single component of a library , Introduction on demand is a must for project creation
(1) install  babel-plugin-component :

npm install babel-plugin-component -D

(2) With elementUI For example , take .babelrc It is amended as follows :

{
"presets": [["es2015", { "modules": false }]],
"plugins": [
[
"component",
{
"libraryName": "element-ui",
"styleLibraryName": "theme-chalk"
}
]
]
}

(3) stay main.js Introduce some components as needed :

import Vue from 'vue';
import { Button, Select } from 'element-ui';
Vue.use(Button)
Vue.use(Select)

10、 Server rendering SSR or pre-render

Server side rendering refers to Vue Render the whole tag on the client side html The work of the segment is completed on the server , Formed by the server html This process is called server rendering .

Server rendering :

(1) Advantages of server-side rendering :

  • better SEO: because SPA The content of the page is through Ajax obtain , And search engine crawling tools don't wait Ajax After asynchronous completion, the content of the page can be retrieved , So in SPA Is not able to grab the page through Ajax What you get ; and SSR It is to return the rendered page directly from the server ( Data is already included in the page ), So search engine crawler can grab the rendered page ;
  • Faster content arrival time ( Faster first screen loading ):SPA Will wait for all Vue The compiled js After all files are downloaded , To start rendering the page , File download and so on need a certain time and so on , So the first screen rendering takes a certain amount of time ;SSR Render the page directly from the server and return to the display directly , No need to wait for download js File and re rendering, etc , therefore SSR Faster content arrival time ;

(2) Disadvantages of server-side rendering :

  • More development constraints : For example, server-side rendering only supports beforCreate and created Two hook functions , This will cause some external extension libraries to need special handling , In order to run in the server rendering application ; And with a fully static single page application that can be deployed on any static file server SPA Different , Server rendering application , Need to be in Node.js server Running environment ;
  • More server load : stay Node.js Render the complete application , Obviously it's better than just providing static files server More occupation CPU resources , So if you expect to use it in a high traffic environment , Please prepare the corresponding server load , And adopt the caching strategy wisely .

pre-render :

If your project's SEO and The first screen rendering is the key index to evaluate the project , Then your project needs server-side rendering to help you achieve the best initial loading performance and SEO. If your Vue The project only needs to improve a few marketing pages ( for example /about, /contact etc. ) Of SEO, Then you may need pre-render , At build time (build time) Simply generate static for a specific route HTML file . The advantage is that setting up pre rendering is simpler , And you can use your front end as a completely static site .

Use prerender-spa-plugin You can easily add settings to pre render .

Webpack Level optimization

1、Webpack Compress the picture

2.1、Webpack Compress the picture

stay vue In addition to the project can be in  vue.config.js  in url-loader Set in limit Size to handle the picture , For less than limit The picture of is transformed into base64 Format , The rest do not operate . So for some larger image resources , When requesting resources , Loading will be slow , We can use  image-webpack-loader To compress pictures :

(1) Install first image-webpack-loader :

npm install image-webpack-loader --save-dev

(2) stay vue.config.js To configure :

{
test: /.(png|jpe?g|gif|svg)(?.*)?$/,
use:[
{
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')
}
},
{
loader: 'image-webpack-loader',
options: {
bypassOnDebug: true,
}
}
]
}

2、 Reduce ES6 To ES5 Redundant code for

Babel The plug-in will ES6 Code to ES5 Code will inject some auxiliary functions , For example, the following ES6 Code :

class HelloWebpack extends Component{...}

This code is then converted into something that works ES5 The code needs the following two auxiliary functions :

babel-runtime/helpers/createClass // Used to implement class grammar
babel-runtime/helpers/inherits // Used to implement extends grammar 

By default , Babel These dependent auxiliary function codes are embedded in each output file , If multiple source files depend on these helper functions , Then the code of these auxiliary functions will appear many times , Causes code redundancy . In order not to let the code of these auxiliary functions repeat , You can rely on them through  require('babel-runtime/helpers/createClass')  How to import , So you can make them appear only once .babel-plugin-transform-runtime  Plugins are used to do this , Replace relevant auxiliary functions with import statements , Thereby reducing babel The file size of the compiled code .

(1) Install first  babel-plugin-transform-runtime :

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

(2) modify .babelrc The configuration file is :

"plugins": [
"transform-runtime"
]

3、tree-sharking

webpack5 Yes tree-shaking The friendliness of the support is exciting , about webpack4 It's basically enough , Don't talk too much nonsense , It's necessary for the production environment , Add it up !!!

4、 Extract public code

If the third-party library and common modules of each page are not extracted in the project , Then the project will have the following problems :

  • The same resources are loaded repeatedly , Waste user traffic and server costs .
  • Each page needs to load too many resources , The first screen load of the web page is slow , Impact on user experience .

So we need to separate the common code of multiple pages into separate files , To optimize the above .Webpack Built in for extracting multiple Chunk Plugins for the public part of CommonsChunkPlugin, We are in the project CommonsChunkPlugin The configuration is as follows :

// All in package.json It depends on the package , Will be packed into vendor.js In this file .
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 relationship of code modules
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest',
chunks: ['vendor']
})

5、 Template precompile

When using DOM Internal formwork or JavaScript When the string template inside , The template is compiled at run time as a rendering function . Usually the process is fast enough , But performance sensitive applications are best avoided .

The easiest way to precompile a template is to use a single file component —— The relevant build settings will automatically pre compile , So the built code already contains the compiled rendering function instead of the original template string .

If you use webpack, And like to separate JavaScript And template files , You can use vue-template-loader, It can also convert template files into JavaScript Rendering function .

6、 Extract component's CSS

When using a single file component , Components within the CSS Will style Label the way through JavaScript Dynamic Injection . There's a little runtime overhead , If you use server-side rendering , This will lead to a period of “ No style content flicker (fouc) ” . Put all components of CSS Extracting to the same file can avoid this problem , Will also let CSS Better compression and caching .

vue-cli Of webpack The template has been pre configured

7、 Optimize SourceMap

After the project is packaged , It will package multiple file codes in development into one file , And compressed 、 Remove the extra space 、babel After compiling , Finally, the compiled code will be used in the online environment , So there will be a big difference between the processed code and the source code , When there is bug When , We can only locate the code after compression , Unable to locate code in development environment , For development, it is not easy to locate the mode , therefore sourceMap There is , It is to solve the problem of bad modulation code .

SourceMap The optional values of are as follows (+ More numbers , Represents the faster ,- More numbers , The slower the speed , o For medium speed )
image

 Development environment recommendation :cheap-module-eval-source-map
Recommended production environment :cheap-module-source-map

Here's why :

  • cheap: The column information in the source code has no effect , So we don't want the packed file to contain column related information , Only the row information can establish the dependency relationship before and after packing . So whether it's a development environment or a production environment , We all want to add cheap The basic type to ignore the column information before and after packing ;
  • module : Whether it's a development environment or a formal environment , We all want to be able to locate bug The specific location of the source code , For example, some Vue The document is wrong , We want to be specific Vue file , So we also need module To configure ;
  • soure-map :source-map It will generate independent modules for each packaged module soucemap file , So we need to increase source-map attribute ;
  • eval-source-map:eval Packing code is very fast , Because it doesn't make map file , But you can eval Use a combination of eval-source-map Use will map Document to DataURL The form exists in packaged js In file . Don't use... In a formal environment eval-source-map, Because it increases the size of the file , But in the development environment , You can try it out , Because they pack fast .

8、 Output analysis of construction results

Webpack The output code is very readable and the file is very large , It gives us a headache . For the sake of simplicity 、 Visually analyze the output , There are many visual analysis tools in the community . These tools graphically show the results more directly , Let's quickly understand the problem . Analysis tools :webpack-bundle-analyzer .

We are in the project  vue.config.js  To configure :

if (config.build.bundleAnalyzerReport) {
var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
webpackConfig.plugins.push(new BundleAnalyzerPlugin());
}

perform  $ npm run build --report  After the analysis report is generated

Unified optimization

1、 Browser cache

In order to improve the speed of loading pages , It is necessary to cache static resources , Classify according to whether the request needs to be reissued to the server , take HTTP There are two types of caching rules ( Mandatory cache , Compare cache )

2、CDN Use

Static external file is too large , Consider using stable CDN Services to load resources , Reduce the volume of the project

stay vue.config.js Add the following configuration to the configuration

configureWebpack: config => {
if (process.env.NODE_ENV === 'production') {
// config.plugins.push(new BundleAnalyzerPlugin())
config.externals = {
lodash: '_',
vue: 'Vue',
'vue-router': 'VueRouter',
vuex: 'Vuex',
'element-ui': 'ELEMENT',
axios: 'axios',
highcharts: 'Highcharts',
echarts: 'echarts',
'v-charts': 'VeIndex',
sortablejs: 'Sortable'
}
} else {
config.plugins.push(
new HardSourceWebpackPlugin({
cacheDirectory: '../.cache/hard-source/[confighash]'
})
)
}
}

First in index.html The file import CDN file ( Including supporting js and css file ), And then in main.js File to import the relevant components

<link rel="stylesheet" href="https://cdn.bootcss.com/element-ui/2.8.2/theme-chalk/index.css" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/v-charts/lib/style.min.css">
<script src="https://cdn.bootcss.com/vue/2.6.10/vue.runtime.min.js"></script>
<script src="https://cdn.bootcss.com/vue-router/3.0.1/vue-router.min.js"></script>
<script src="https://cdn.bootcss.com/vuex/3.0.1/vuex.min.js"></script>
<script src="https://cdn.bootcss.com/axios/0.18.0/axios.min.js"></script>
<script src="https://cdn.bootcss.com/element-ui/2.8.2/index.js"></script>
<script src="https://cdn.bootcss.com/highcharts/7.1.1/highcharts.js"></script>
<script src="https://cdn.bootcss.com/highcharts/7.1.1/highcharts-3d.js"></script>
<script src="https://cdn.jsdelivr.net/npm/echarts/dist/echarts.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/v-charts/lib/index.min.js"></script>

3、Chrome Performance Find performance bottlenecks

Chrome Of Performance The panel can record... For a period of time js Execution details and time . Use Chrome The steps for developer tools to analyze page performance are as follows .

  1. open Chrome Developer tools , Switch to Performance panel
  2. Click on Record Start recording
  3. Refresh the page or expand a node
  4. Click on Stop Stop recording
版权声明
本文为[Master of Wannian Da Ye Yi]所创,转载请带上原文链接,感谢

  1. [front end -- JavaScript] knowledge point (IV) -- memory leakage in the project (I)
  2. This mechanism in JS
  3. Vue 3.0 source code learning 1 --- rendering process of components
  4. Learning the realization of canvas and simple drawing
  5. gin里获取http请求过来的参数
  6. vue3的新特性
  7. Get the parameters from HTTP request in gin
  8. New features of vue3
  9. vue-cli 引入腾讯地图(最新 api,rocketmq原理面试
  10. Vue 学习笔记(3,免费Java高级工程师学习资源
  11. Vue 学习笔记(2,Java编程视频教程
  12. Vue cli introduces Tencent maps (the latest API, rocketmq)
  13. Vue learning notes (3, free Java senior engineer learning resources)
  14. Vue learning notes (2, Java programming video tutorial)
  15. 【Vue】—props属性
  16. 【Vue】—创建组件
  17. [Vue] - props attribute
  18. [Vue] - create component
  19. 浅谈vue响应式原理及发布订阅模式和观察者模式
  20. On Vue responsive principle, publish subscribe mode and observer mode
  21. 浅谈vue响应式原理及发布订阅模式和观察者模式
  22. On Vue responsive principle, publish subscribe mode and observer mode
  23. Xiaobai can understand it. It only takes 4 steps to solve the problem of Vue keep alive cache component
  24. Publish, subscribe and observer of design patterns
  25. Summary of common content added in ES6 + (II)
  26. No.8 Vue element admin learning (III) vuex learning and login method analysis
  27. Write a mini webpack project construction tool
  28. Shopping cart (front-end static page preparation)
  29. Introduction to the fluent platform
  30. Webpack5 cache
  31. The difference between drop-down box select option and datalist
  32. CSS review (III)
  33. Node.js学习笔记【七】
  34. Node.js learning notes [VII]
  35. Vue Router根据后台数据加载不同的组件(思考-&gt;实现-&gt;不止于实现)
  36. Vue router loads different components according to background data (thinking - & gt; Implementation - & gt; (more than implementation)
  37. 【JQuery框架,Java编程教程视频下载
  38. [jQuery framework, Java programming tutorial video download
  39. Vue Router根据后台数据加载不同的组件(思考-&gt;实现-&gt;不止于实现)
  40. Vue router loads different components according to background data (thinking - & gt; Implementation - & gt; (more than implementation)
  41. 【Vue,阿里P8大佬亲自教你
  42. 【Vue基础知识总结 5,字节跳动算法工程师面试经验
  43. [Vue, Ali P8 teaches you personally
  44. [Vue basic knowledge summary 5. Interview experience of byte beating Algorithm Engineer
  45. 【问题记录】- 谷歌浏览器 Html生成PDF
  46. [problem record] - PDF generated by Google browser HTML
  47. 【问题记录】- 谷歌浏览器 Html生成PDF
  48. [problem record] - PDF generated by Google browser HTML
  49. 【JavaScript】查漏补缺 —数组中reduce()方法
  50. [JavaScript] leak checking and defect filling - reduce() method in array
  51. 【重识 HTML (3),350道Java面试真题分享
  52. 【重识 HTML (2),Java并发编程必会的多线程你竟然还不会
  53. 【重识 HTML (1),二本Java小菜鸟4面字节跳动被秒成渣渣
  54. [re recognize HTML (3) and share 350 real Java interview questions
  55. [re recognize HTML (2). Multithreading is a must for Java Concurrent Programming. How dare you not
  56. [re recognize HTML (1), two Java rookies' 4-sided bytes beat and become slag in seconds
  57. 【重识 HTML ,nginx面试题阿里
  58. 【重识 HTML (4),ELK原来这么简单
  59. [re recognize HTML, nginx interview questions]
  60. [re recognize HTML (4). Elk is so simple