In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/01 Report--
This article introduces the knowledge of "how to optimize performance in Vue development". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!
Performance optimization is a problem that every developer will encounter, especially in an environment where more and more attention is being paid to experience and increasingly competitive environment. For us developers, it is far from enough to complete iterations and function well. The most important thing is to make the product well, so that more people are willing to use it and let users use it better. This is also the embodiment of the value and ability of our developers.
1. Long list performance optimization 1. Don't be responsive.
For example, member lists, product lists, and so on, are only pure data display, and there is no need to respond to the data without any dynamic changes, which can greatly improve the rendering speed.
For example, using Object.freeze () to freeze an object, MDN describes that the object frozen by this method cannot be modified; that is, new properties cannot be added to the object, existing properties cannot be deleted, enumerable, configurable, writable, and the prototype of the object cannot be modified.
Export default {data: () = > ({userList: []}), async created () {const users = await axios.get ("/ api/users"); this.userList = Object.freeze (users);}}
The responsive source address of Vue2: line src/core/observer/index.js-144looks like this
Export function defineReactive (...) {const property = Object.getOwnPropertyDescriptor (obj, key) if (property & & property.configurable = false) {return}...}
You can see that the direct return that judged configurable as false from the very beginning does not do responsive processing.
A configurable of false means that this property cannot be modified, and the configurable of a frozen object is false.
Responsive flag is added to Vue3 to mark the target object type.
two。 Virtual scrolling
If it is big data's long list, creating too many DOM at one time will be very stuck if you render all of them. At this time, you can use virtual scrolling to render only a small part of the content of the area (including the visual area), and then when scrolling, constantly replace the contents of the visual area to simulate the effect of scrolling.
Refer to vue-virtual-scroller, vue-virtual-scroll-list
The principle is to listen for scrolling events, dynamically update the DOM that needs to be displayed, and calculate the displacement in the view, which also means that the scrolling process needs to be calculated in real time, and there is a certain cost, so if the amount of data is not very large, just use ordinary scrolling.
2. V-for traversal to avoid using v-if at the same time
Why avoid using v-for and v-if at the same time
V-for is a higher priority in Vue2, so during compilation, all list elements are traversed to generate virtual DOM, and then v-if is used to determine that only those that meet the conditions are rendered, which will result in a waste of performance, because what we want is not to generate virtual DOM that does not meet the conditions.
V-if has a higher priority in Vue3, which means that when the judgment condition is an attribute in the list traversed by v-for, v-if cannot get it.
So in some scenarios that need to be used at the same time, you can filter the list by calculating attributes, as follows
{{item.title}} / / Vue2.xexport default {computed: {activeList () {return this.list.filter (item = > {return item.isActive})}} / / Vue3import {computed} from "vue"; const activeList = computed (() = > {return list.filter (item = > {return item.isActive})}) 3. List uses a unique key
For example, if we have a list and we need to insert an element in the middle, what happens if we don't use key or use index as the key? Look at a picture first.
The li1 and li2 shown in the figure will not be re-rendered, which is not controversial. Li3, li4 and li5 will all be re-rendered.
Because when you do not use key or the index of the list as the key, the corresponding position relationship of each element is index, and the result in the above figure directly causes the inserted elements to be changed to all the subsequent elements, so they will all be updated and re-rendered during the patch process.
This is not what we want, what we want is the element added by rendering, and the other four elements will not be re-rendered without any changes.
In the case of using a unique key, the corresponding position relationship of each element is key. Let's take a look at the case where a unique key value is used.
In this way, the li3 and li4 in the figure will not be re-rendered, because the content of the element has not changed and the corresponding position relationship has not changed.
This is why v-for must write key, and it is not recommended to use array index as key in development.
4. Reuse DOM with v-show
V-show: is the rendering component, and then changes the display of the component to block or none v-if: rendering or non-rendering component
So for scenarios where conditions can be changed frequently, use v-show to save performance, especially the more complex the DOM structure, the greater the benefits.
However, it also has a disadvantage, that is, at the beginning of v-show, all the components within the branch will be rendered and the corresponding lifecycle hook functions will be executed, while v-if will only load the components that are hit by the judgment condition, so you need to use appropriate instructions according to different scenarios.
For example, the following uses v-show to reuse DOM, which is better than v-if/v-else
The principle is to use v-if to trigger diff updates when conditions change, and find that the new and old vnode are inconsistent, then remove the entire old vnode, recreate a new vnode, then create a new my-components component, and then go through the process of initialization and render,patch of the component itself, while v-show when the conditions change, the new and old vnode are consistent, so a series of processes such as removal and creation will not be performed.
5. Functional components for stateless components
For some pure presentation components that have no responsive data, no state management, and no lifecycle hook functions, we can set them as functional components to improve rendering performance, because it will be treated as a function, so the overhead is very low.
The principle is that in the patch process, for the virtual DOM generated by the render of functional components, there is no process of recursive subcomponent initialization, so the rendering overhead will be much lower.
It can accept props, but since the instance will not be created, you cannot use this.xx internally to get component properties, as follows
{{value}} export default {props: ['value']} / / or Vue.component (' my-component', {functional: true, / / indicates that the component is a functional component props: {.}, / optional / / the second parameter is the context, there is no this render: function (createElement, context) {/ /.}}) 6. Sub-component segmentation
Let's look at an example first.
{{someThing ()}} export default {props: ['number'], methods: {someThing () {/ * time-consuming task * /}
In the above code, every time the number passed by the parent component changes, it will re-render and re-execute the time-consuming task of someThing
So for optimization, one is to use the calculation attribute, because the calculation attribute itself has the property of caching the calculation result.
The second is to split into sub-components, because the update of Vue is component granularity, although the second data change will lead to re-rendering of the parent component, but the sub-component will not re-render, because there is no internal change, time-consuming tasks will not be re-executed, so the performance is better, the optimization code is as follows
Export default {components: {methods: {someThing () {/ * time-consuming task * /}}, render (h) {return h ('div', this.someThing ())} 7. Variable localization
To put it simply, it is to save the variables that will be referenced many times, because every time you visit this.xx, because it is a responsive object, getter will be triggered every time, and then the relevant code collected by dependencies will be executed. If you use variables more times, the performance will naturally be worse.
In terms of requirements, it is enough for a variable to perform a dependency collection in a function, but many people habitually write a lot of this.xx in the project, ignoring what is done behind the this.xx, which will lead to performance problems.
For example, the following example
{{result}} import {someThing} from'@ / utils'export default {props: ['number'], computed: {base () {return 100}, result () {let base = this.base, number = this.number / / saved for (let I = 0; I
< 1000; i++) { number += someThing(base) // 避免频繁引用this.xx } return number }}}8. 第三方插件按需引入 比如 Element-UI 这样的第三方组件库可以按需引入避免体积太大,特别是项目不大的情况下,更没有必要完整引入组件库 // main.jsimport Element3 from "plugins/element3";Vue.use(Element3)// element3.js// 完整引入import element3 from "element3";import "element3/lib/theme-chalk/index.css";// 按需引入// import "element3/lib/theme-chalk/button.css";// ...// import { // ElButton, // ElRow, // ElCol, // ElMain, // .....// } from "element3";export default function (app) { // 完整引入 app.use(element3) // 按需引入 // app.use(ElButton);}9. 路由懒加载 我们知道 Vue 是单页应用,所以如果没有用懒加载,就会导致进入首页时需要加载的内容过多,时间过长,就会出现长时间的白屏,很不利于用户体验,SEO 也不友好 所以可以去用懒加载将页面进行划分,需要的时候才加载对应的页面,以分担首页的加载压力,减少首页加载时间 没有用路由懒加载: import Home from '@/components/Home'const router = new VueRouter({ routes: [ { path: '/home', component: Home }]}) 用了路由懒加载: const router = new VueRouter({routes: [ { path: '/home', component: () =>Import ('@ / components/Home')}, {path:'/ login', component: require ('@ / components/Home') .default}]})
When entering this route, it will take the corresponding component, and then run import to compile and load the component, which can be understood as the resolve mechanism of Promise.
Import:Es6 syntax specification, compile-time calls, is a deconstruction process, does not support variable functions, etc.
Require:AMD specification, runtime calls, is an assignment process, supports variable calculation functions, etc.
For more information on front-end modularization, please see my another article, a detailed summary of the front-end modularization specification.
10. Keep-alive cache page
For example, after the form input page goes to the next step, when you go back to the form page, you need to keep the form input, such as in the list page > details page > list page, so as to jump back and forth.
We can all cache the components through the built-in components without uninstalling them when the components are switched, so that when we return again, we can quickly render from the cache instead of re-rendering to save performance.
You only need to wrap the components you want to cache.
You can also use include/exclude to cache / not cache specified components
The current component state can be obtained through two lifecycle activated/deactivated
11. Destruction of events
When a Vue component is destroyed, it automatically unbinds all of its instructions and event listeners, but only for the events of the component itself
For timers, addEventListener registered listeners, etc., they need to be manually destroyed or unbound in the lifecycle hooks of component destruction to avoid memory leaks.
Export default {created () {this.timer = setInterval (this.refresh, 2000) addEventListener ('touchmove', this.touchmove, false)}, beforeDestroy () {clearInterval (this.timer) this.timer = null removeEventListener (' touchmove', this.touchmove, false)} 12. Picture lazy load
Lazy loading of pictures means that for pages with a lot of pictures, in order to improve the loading speed of the page, only the pictures in the visual area are loaded, and those outside the visual area wait until scrolled to the visual area before loading.
Some UI frameworks come with this feature, but what if they don't?
Recommend a third-party plug-in vue-lazyload
Npm I vue-lazyload-S VueLazyload / main.jsimport VueLazyload from 'vue-lazyload'Vue.use (VueLazyload) / / then you can use v-lazy lazily to load pictures on the page.
Or build your own wheel and manually encapsulate a custom instruction. Here you encapsulate a version that is compatible with all browsers, mainly to judge whether the browser supports IntersectionObserver API or not. If you support it, you can use it to load lazily. If you don't support it, you can implement it by listening for scroll events and throttling.
Const LazyLoad = {/ / install method install (Vue, options) {const defaultSrc = options.default Vue.directive ('lazy', {bind (el, binding) {LazyLoad.init (el, binding.value, defaultSrc)}, inserted (el) {if (IntersectionObserver) {LazyLoad.observe (el)} else {LazyLoad.listenerScroll (el)}},})} / / initialize init (el, val, def) {el.setAttribute ('data-src', val) el.setAttribute (' src', def)} / / use IntersectionObserver to listen to elobserve (el) {var io = new IntersectionObserver ((entries) = > {const realSrc = el.dataset.src if (entries [0] .isIntersecting) {if (realSrc) {el.src = realSrc el.removeAttribute ('data-src')}}) io.observe (el)}, / / listen to scroll event listenerScroll (el) {const handler = LazyLoad.throttle (LazyLoad.load) LazyLoad.load (el) window.addEventListener ('scroll', () = > {handler (el)})}, / / load real picture load (el) {const windowHeight = document.documentElement.clientHeight const elTop = el.getBoundingClientRect (). Top const elBtm = el.getBoundingClientRect (). Bottom const realSrc = el.dataset.src if (elTop-windowHeight)
< 0 && elBtm >0) {if (realSrc) {el.src = realSrc el.removeAttribute ('data-src')}}, / / Throttle throttle (fn, delay) {let timer let prevTime return function (... args) {const currTime = Date.now () const context = this if (! prevTime) prevTime = currTime clearTimeout (timer) if (currTime-prevTime > delay) {prevTime = currTime fn.apply (context) Args) clearTimeout (timer) return} timer = setTimeout (function () {prevTime = Date.now () timer = null fn.apply (context, args)}, delay)},} export default LazyLoad
In use, use v-LazyLoad instead of src.
So much for the content of "how to optimize performance in Vue development". Thank you for reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.