当前位置: 首页 > Web前端 > vue.js

Vue2.0性能优化解决方案总结

时间:2023-03-31 14:26:19 vue.js

随着互联网的发展,越来越多的公司在使用Vue,但是随着项目越来越大,不可避免地会带来一系列的性能问题。这些问题很头疼,同时我也学习了Vue的性能优化,让自己在立项前就可以避免性能问题,避免不必要的返工。为了以后能够快速的找到相关的学习内容,在此记录一下,以备日后查看。同时,我也想把这些内容总结一下,希望能帮助到更多的朋友一起学习,一起成长。打架~这时候很多朋友可能会说,既然Vue3.0都快要发布了,为什么还要优化2.0项目呢?因为公司80%的项目都是Vue2.0项目,迁移成本太高,只能针对性能进行优化调整。废话不多说,直接开始。在使用异步组件Vue-cli打包的时候,所有的依赖文件都会被打包成一个很大的js文件。当用户浏览网页时,需要将整个js文件拉过来,会导致页面初始化。页面会长时间白屏,这个题确实比较难。想象一下,如果页面上有很多功能点,每个功能点对应不同的功能弹窗或窗体。首先,页面上有很多功能。我们不知道用户要使用哪个功能,需要弹出哪个功能。对于弹窗或者表单,在异步组件的情况下,Vue-cli在打包的时候会把异步组件打包到一个单独的文件中,只在用户使用的时候加载js文件的内容,这样既可以渲染首屏会起到一定的优化作用。看看官网对异步组件的描述:在大型应用中,我们可能需要将应用分成更小的代码块,只在需要的时候从服务器加载一个模块。为了简化事情,Vue允许您将组件定义为异步解析组件定义的工厂函数。Vue只会在组件需要渲染时触发工厂函数,并将结果缓存起来以备将来重新渲染。//代码截取自Vue官网Vue.component('async-webpack-example',()=>import('./my-async-component'))Vue官方提供异步组件加载Loadingasynchronouscomponent://代码从Vue官网截取constAsyncComponent=()=>({//需要加载的组件(应该是`Promise`对象)component:import('./MyComponent.vue'),//使用的组件加载异步组件时loading:LoadingComponent,//加载失败时使用的组件error:ErrorComponent,//显示组件加载时的延迟时间,默认为200(毫秒)delay:200,//如果超时provided,组件加载也超时,//使用加载失败时使用的组件。默认值为:`Infinity`timeout:3000})使用异步组件需要注意以下几点:如果只有异步的需要加载一些组件,先加载部分,然后再加载oad部分,那么可以直接使用vue官网直接使用setTimeOut。如果点击加载,一定要写v-if,否则会报错,说测试组件没有注册。v-if是惰性的,只有第一次为真时才会开始初始化。初始化减少DOM渲染还是上面说的情况。页面中功能点很多,但是弹窗比较多。实际上,对于这些弹窗,一开始只考虑一个弹窗,为了节省页面。初步渲染图,但在实际开发过程中,虽然解决了一些问题,但似乎开发过程并没有那么乐观。弹窗里面有很多v-if和v-show,太难维护了。我也想过使用组件,但是一个的压力可想而知不是一点点。但是这个问题仍然存在,需要解决。在没有解决办法的情况下,最后还是用两个flag来控制弹窗的显示和隐藏。上面代码中,用了两个标志值来控制Dialog,一个是控制Dialog的渲染Dialog,One控制Dialog的显示。当用户第一次进入页面时,不会渲染对话框元素。当用户点击按钮时,相应的对话框将被渲染。当Dialog的DOM渲染完成后,用于显示Dialog。注意:$nextTick中显示的对话框是为了保证对话框的动画效果。如果不使用$nextTick,对话框会突然出现。在组件内部请求数据当你在做业务的时候,可能会出现这样的情况。点击按钮后,需要获取的数据详情会在弹窗或侧滑中呈现。这种情况一定不少见。我开始做的时候是直接在点击的时候获取被点击元素的详细数据,当数据返回的时候,我把数据放在数据缓存中,然后传给组件。这不是不可以,也是可以的。这将面临一个问题。第一点,当弹窗渲染元素过多时,侧滑或弹窗的动画效果会很卡。有的甚至不动,瞬间就消失了。最后经过反复实验,将数据放到弹窗内部组件中去请求,保证出现弹窗或侧滑时内置元素较少。当没有请求返回数据时,需要隐藏弹出框组件中的所有元素。改用Loading,当使用弹窗或者侧滑关闭的时候,需要销毁显示的组件,保证释放里面的数据占用的内存,还是有利于整体优化的。由于业务情况的复杂性,难免在某个地方加入各种条件的渲染,例如:v-if="isHide&&selectList.length&&(isA||isB)",这里只是简单的exampleChestnuts在实际开发过程中可能远比这个复杂。这种表达方式虽然看起来是可以维护的,但是长此以往会暴露问题,不利于维护。在这种情况下,可以使用方法或计算来适当地封装方法。其实这样做的好处就是方伯尼判断的是同一个表情。如果其他元素有类似需求,可以直接使用该方法。v-for&&v-bind:key在使用v-for循环的过程中,使用这样的代码:key="item.id"对代码的性能是非常不友好的,因为当data数据更新时,新的状态值将与旧状态值进行比较,Vue在使用多种diff算法时可以更快地定位虚拟DOM的元素。其实说到这里,我们就需要说明下面这个key在Vue.js中起到什么样的作用了。key属性其实是对Vue的一种优化。上面说了,是为了更准确高效的定位虚拟DOM,相当于用key数组中的某个预算绑定在一起。如果那个key对应的数据发生变化,直接更新对应的DOM即可。简而言之,可以直接使用索引作为键,但是如果是大列表,最好不要使用索引作为键。比如从数组中删除一个元素,这个元素后面的元素的所有下标都会前移一个,而前面的key对应的data和DOM就会乱了。除非重新匹配密钥,否则很容易出错。如果重新匹配key,相当于重新渲染所有的,违背了使用key来优化和更新dom的初衷。不过对于vue玩的非常好的同学,可以忽略这个。Object.freeze如果对Vue有一定的了解,就会知道Vue是通过Object.defineProperty来劫持数据最终实现视图响应数据的变化,但是在实际开发过程中,页面的某些部分可能不需要修改的。双向绑定只是为了简单的渲染。绑定数据后,不需要做任何更改时,可以使用Object.freeze解除数据绑定。先介绍下面的Object.freeze内置函数,它是用来连接对象的。冻结的对象不会被修改。无法向此对象添加新属性,无法删除现有属性,也无法修改此对象的现有属性的枚举。性、可配置性和可写性。另外,对象冻结后,对象的原型是不能修改的。当数据量很大时,这可以显着减少组件的初始化时间。这里要注意的一点是对象一旦被冻结,就不能再修改了。但是这里有个问题需要注意,敲黑板!敲黑板!敲黑板!Object.freeze虽然可以在一定程度上帮助我们提升一些数据性能,但是还是需要谨慎使用。避免导致数据无响应的问题。如果再次使用Object.freeze属性为其对象属性赋值,将抛出无法赋值给对象的只读属性*的错误。如果数据量小,用这种方法是感觉不到性能提升的。只有数据量大的时候,才会感觉到数据的明显变化。渲染前处理渲染数据时,后台返回的数据与UI设计图中要求的数据格式不一致。比如需要在列表中展示一个时间,但是后端返回的是时间戳,那么前端就需要对这部分数据进行处理。一般来说,有一些方法可以处理这种情况,使用函数,使用过滤器,以及在渲染前处理数据。作者这里建议在渲染前处理所有数据,为什么?数据渲染完成后,会执行里面的函数或者过滤器,这会对页面渲染造成明显的额外负担。熟悉Vue3.0的可以知道,在Vue3.0中去掉了filter函数,推荐使用computed来达到同样的效果。猜猜内容:你可能也发现了,filter给页面渲染带来的额外负担,对于提升页面的性能并没有太大的作用。functional没有多少功能组件需要方法。在Vue中,为了表明一个模板应该被编译成一个功能组件,在模板中添加了functional属性。如果项目中使用的组件不是有状态组件,那么可以使用功能属性将这个组件替换为功能组件。功能组件(不要与Vue的渲染功能混淆)是不包含状态或实例的组件。功能组件是没有状态或实例的组件。由于函数式组件没有状态,所以不需要像Vue的数据响应那样做初始化动作。功能组件仍然会像incoming和outgoingprops一样响应数据更新,但是功能组件本身,因为它们不维护自己的状态,所以无法知道它们的数据是否发生了变化。在大型项目中使用函数式组件后,DOM渲染有明显的提升。由于功能组件没有状态,因此不需要像Vue的反应系统那样进行额外的初始化。当传入新的props时,功能组件仍会对变化做出反应,但在组件本身内部,由于它不维护自己的状态,因此无法知道数据何时发生变化。在许多情况下,功能组件可能并不合适。毕竟,使用JavaScript框架的目的是构建更具反应性的应用程序。在Vue中,如果没有适当的反应系统,就无法做到这一点。假设我们的组件接受一个prop.user,它是一个具有firstName和lastName的对象,我们想要呈现一个显示用户全名的模板。在函数式子组件处理业务页面中会有很多列表,列表中会出现各种复杂的情况。这时候可以将一些繁重的业务处理存放在它的子组件中。代码对比:优化后:props:number改变组件重新渲染时,heavy为long任务也将重新执行。但是,如果可以将与父组件不相互依赖的元素拆分成一个组件,当需要重新渲染父组件时,子组件不会因为与父组件没有依赖关系而重新渲染,响应性能也可以提高。局部作用域开发过程中经常会用到一些计算属性或Util函数。如果我们不断地使用它,但是这个值确实是固定值,造成了很大的性能浪费。如果我们要用到这些属性,最好的办法就是把对应的值取出来再用。总结以上是我调查资料得到的Vue性能优化和个人项目中的一些小经验有可能文章中的一些想法有些问题。欢迎大家在评论区指出,我们一起学习进步。