vue性能优化方法有哪些,vue前端优化

  vue性能优化方法有哪些,vue前端优化

  演示代码是用Vue3 ts Vite写的,但也列出了适用于Vue2的优化技术,有一定的参考价值。感兴趣的朋友可以参考一下。

  

目录

  代码优化

  使用v-for键

  使用v-if/v-else-if/v-else中的key合理选择v-if和v-show。

  使用简单计算属性功能组件(Vue2)拆分组件

  使用局部变量

  使用保持活动状态

  事件的破坏

  图片加载

  采用合理的数据处理算法。

  其他的

  屏幕/音量优化

  优化的体积代码分段

  网络

  演示代码是用Vue3 ts Vite写的,但也将列出适用于Vue2的优化技术。如果一个优化只适用于Vue3或Vue2,我会在标题中把它标出来。

  

代码优化

  

v-for 中使用 key

  使用v-for更新渲染元素列表时,默认使用原地复用策略;当列表被修改时,他会根据键值判断某个值是否被修改。如果修改了,会重新渲染;否则,前面的元素将被重用。

  使用钥匙的注意事项:

  不要使用可能重复或可能改变的键值(控制台也会给出提醒)

  不要使用数组的索引作为键值,因为如果一个元素被插入到数组中,它后面的元素的索引会改变。

  如果数组中没有唯一的键值,请考虑向其中添加一个键字段。Symbol()的值可以保证唯一性。

  

v-if/v-else-if/v-else 中使用 key

  很多人可能忽略了这一点。

  原因:默认情况下,Vue会尽可能高效地更新DOM。这意味着当它在相同类型的元素之间切换时,它将修补现有的元素,而不是删除旧的元素,然后在相同的位置添加一个新元素。如果不同的元素被识别为相同的,就会出现意想不到的副作用。

  如果只有一个v-if,而没有v-else或v-if-else,则不需要添加key。

  与v-for的key相比,v-if/v-else-if/v-else中的key相对简单,我们可以直接写一个固定的字符串或者数组。

  过渡

  按钮

  v-if=isEditing

  v-on:click=isEditing=false

  救援

  /按钮

  按钮

  v-否则

  v-on:click=isEditing=true

  编辑

  /按钮

  /过渡。v-enter-active,v-离开-活动{

  过渡:全1;

  }。回车。v-离开到{

  不透明度:0;

  transform:translate y(30px);

  }。v-离开-活动{

  位置:绝对;

  }

  比如上面的代码,你会发现虽然按钮上加了转场效果,但是不加按键开关是无法触发转场的。

  V-for和v-if不应一起使用(Vue2)

  这种优化技术仅限于调整Vue2和Vue3中v-for和v-if的优先级。

  这个大家都知道。

  不要在同一个元素上同时使用v-if和v-for。Vue2.x风格指南指南

  原因是v-for的优先级高于v-if,所以当它们用在同一个标签上时,每次渲染都会先循环,再进行条件判断。

  注意:Vue3中v-if的优先级高于v-for,所以当v-for和v-if一起使用时,效果类似于Vue2中提升v-if。

  比如下面这段代码在Vue2中是不推荐的,Vue会给出相应的警告。

  保险商实验所

  li v-for=用户中的用户 v-if=user.active

  {{用户名}}

  /李

  /ul

  我们应该尽力将v-if移到更高的级别,或者使用计算属性来处理数据。

  ul v-if=active

  li v-for=用户中的用户

  {{用户名}}

  /李

  /ul

  如果不希望循环内容有不必要的上级容器,那么可以选择使用template作为其父元素。浏览器不会将模板呈现为DOM节点。

  如果我想判断遍历对象中每一项的内容来选择渲染数据,我可以使用computed来过滤遍历对象。

  //js

  let users active=computed(()=users . filter(user=user . active))

  //模板

  保险商实验所

  Li v-for= users active中的用户

  {{用户名}}

  /李

  /ul

  

合理的选择 v-if 和 v-show

  v-if和v-show的区别大家都很熟悉;V-if通过直接操作DOM的删除和添加来控制元素的显示和隐藏;V-show通过控制DOM的显示CSS的熟悉程度来控制元素的显示和隐藏。

  因为添加/删除DOM的性能远远低于操作DOM的CSS属性的性能

  因此,当元素需要频繁显示/隐藏时,我们使用v-show来提高性能。

  当元素不需要频繁的显示/隐藏变化时,我们可以通过v-if移除DOM,这样可以节省浏览器渲染这个DOM的一部分所需的资源。

  

使用简单的 计算属性

  复杂的计算属性应该分成尽可能多的简单属性。

  易于测试

  当每个计算的属性都包含一个非常简单且很少依赖的表达式时,编写测试来确保它正确工作将会更容易。

  易于阅读

  简化计算属性要求您为每个值指定一个描述性名称,即使该名称不可重复使用。这使得其他开发人员(以及将来的您)更容易关注他们关心的代码,并弄清楚发生了什么。

  更好地“拥抱变化”

  任何可以命名的值都可以在视图中使用。例如,我们可能想要显示一条消息来告诉用户他们已经节省了多少钱;税也可以计算,但它们可以单独列出,而不是作为总价的一部分。

  小的、专用的计算属性减少了信息使用的假设限制,所以当需求改变时不需要重构。

  Vue2风格指南指南

  Computed大家都很熟悉,当表达式中依赖的响应式数据发生变化时,它会重新计算。如果我们在一个计算属性中写一个更复杂的表达式,那么它所依赖的响应数据就会变得更加随意。当任何一个依赖关系改变时,整个表达式都需要重新计算。

  让price=computed(()={

  设基本价格=制造成本/(1 -利润率)

  返回(

  底价-

  基本价格*(折扣百分比 0)

  )

  })

  当制造商成本、利润率和折扣百分比中的任何一个发生变化时,将重新计算整个价格。

  但是如果我们把它改成下面这样

  设base price=computed(()=manufactureCost/(1-利润率))

  let discount=computed(()=base price *(discount percent 0))

  让final price=computed(()=base price-discount)

  当discountPercent发生变化时,只会重新计算discount和finalPrice,但由于computed的缓存功能,不会重新计算basePrice。

  

functional 函数式组件(Vue2)

  请注意,这仅用作Vue2中的一种优化方法。在3.x中,有状态组件和功能组件之间的性能差异已经大大减小,在大多数用例中可以忽略不计。所以在sfc上使用functional的开发者的迁移路径是删除这个属性,将props的所有引用重命名为$props,将attrs重命名为$attrs。

  优化前

  模板

  div class=cell

  div v-if=value class=on/div

  第五节-else class= off /节

  /div

  /模板

  脚本

  导出默认值{

  道具:[值],

  }

  /脚本

  优化后

  模板功能

  div class=cell

  div v-if= props . value class= on /div

  第五节-else class= off /节

  /div

  /模板

  脚本

  导出默认值{

  道具:[值],

  }

  /脚本

  没有这个(没有实例)

  没有响应数据。

  

拆分组件

  什么?你写了1000多行代码的vue文件?

  合理拆分组件不仅可以优化性能,还可以使代码更清晰,可读性更强。单一功能原则

  起源于https://slides.com/akryum/vueconfus-2019#/4/0/3.

  优化前

  模板

  div:style= { opacity:number/300 }

  div{{ heavy() }}/div

  /div

  /模板

  脚本

  导出默认值{

  道具:[数字],

  方法:{

  heavy () { /*繁重的任务*/}

  }

  }

  /脚本

  优化后

  模板

  div:style= { opacity:number/300 }

  ChildComp/

  /div

  /模板

  脚本

  导出默认值{

  道具:[数字],

  组件:{

  子组件:{

  方法:{

  heavy () { /*繁重的任务*/}

  },

  渲染(h) {

  返回h(div ,this.heavy())

  }

  }

  }

  }

  /脚本

  因为Vue的更新是组件粒度的,虽然每一帧都是通过数据修改重新渲染的,但是ChildComp不会重新渲染,因为它内部没有响应的数据变化。因此,优化的组件不会在每次呈现时都执行耗时的任务。

  

使用局部变量

  优化前

  模板

  div:style= { opacity:start/300 } { { result } }/div

  /模板

  脚本

  从“@/utils”导入{ heavy }

  导出默认值{

  道具:[开始],

  计算值:{

  base () { return 42 },

  结果(){

  让结果=this.start

  for(设I=0;i 1000i ) {

  结果=重(this.base)

  }

  回送结果

  }

  }

  }

  /脚本

  优化后

  模板

  div :style={ opacity: start/300 }

  {{ result }}/div

  /模板

  脚本

  从“@/utils”导入{ heavy }

  导出默认值{

  道具:[开始],

  计算值:{

  base () { return 42 },

  结果(){

  const base=this.base

  让结果=this.start

  for(设I=0;i 1000i ) {

  结果=重(基础)

  }

  回送结果

  }

  }

  }

  /脚本

  下面是优化前后组件的计算属性结果实现的区别。优化前的组件在计算过程中多次访问this.base,而优化后的组件在计算前使用局部变量base缓存this.base,然后直接访问base。

  那么为什么这种差异会造成性能的差异呢?原因是每次访问this.base,因为this.base是一个响应式对象,它的getter会被触发,然后执行依赖集合的相关逻辑代码。类似的逻辑执行得更频繁。如示例中,数百个组件循环更新,每个组件触发计算的重新计算,然后依赖关系收集的相关逻辑被多次执行,因此性能自然下降。

  从需求的角度来说,this.base执行一次依赖关系收集就足够了,将其getter求值结果返回给局部变量base,这样在再次访问base时就不会触发getter,也不会遵循依赖关系收集的逻辑,性能自然会得到提升。

  来揭秘Vue.js的九大性能优化技巧

  

使用 KeepAlive

  当一些渲染成本高的组件需要频繁切换时,可以使用keep-alive来缓存这个组件。

  使用keep-alive后,keep-alive包装的组件的vnode和DOM会在第一次渲染后缓存,然后下一次组件再次渲染时,直接从缓存中获取对应的vnode和DOM,再进行渲染。不需要再经历组件初始化、渲染、补丁等一系列过程,减少了脚本的执行时间,性能更好。

  注意:滥用keep-alive只会让你的应用更加卡顿,因为长时间占用更多内存。

  

事件的销毁

  当一个组件被销毁时,我们应该清除组件中添加的全局事件和计时器,以防止内存泄漏。

  Vue3的HOOK允许我们把事件的声明和销毁写在一起,可读性更强。

  函数scrollFun(){ /*.*/}

  document . addevent listener( scroll ,scrollFun)

  onBeforeUnmount(()={

  document . removeeventlistener( scroll ,scrollFun)

  })

  Vue2还是可以通过$once达到这个效果的。当然,你也可以在optionsAPI beforeDestroy中销毁事件,但我更倾向于前者的写法,因为后者会让同样功能的代码更加分散。

  函数scrollFun(){ /*.*/}

  document . addevent listener( scroll ,scrollFun)

  这个。$once(hook:beforeDestroy ,()={

  document . removeeventlistener( scroll ,scrollFun)

  })

  函数scrollFun(){ /*.*/}

  导出默认值{

  已创建(){

  document . addevent listener( scroll ,scrollFun)

  },

  销毁前(){

  document . removeeventlistener( scroll ,scrollFun)

  }

  }

  

图片加载

  惰性图像加载:适用于页面上有很多图像,并且不能全部显示在一个屏幕上的情况。vue-lazyload插件为我们提供了一个方便的镜像惰性加载指令v-lazy。

  但是,并不是所有的图片都适合懒人加载。比如横幅、相册等。更推荐使用图片预加载技术,当前显示的图片的上一张图片和下一张图片会先下载。

  

采用合理的数据处理算法

  这种相对比较测试数据结构和算法的基础。

  例如,将数组转换为多级结构的方法。

  /**

  *数组到树结构,时间复杂度O(n)

  * @param列表数组

  * @param idKey元素idKey

  * @param parIdKey元素父id键

  * @param parId第一级根节点的父Id值

  * @return {[]}

  */

  函数listToTree (list,idKey,parIdKey,parId) {

  设map={ };

  假设结果=[];

  设len=list.length

  //构建地图

  for(设I=0;我leni ) {

  //将数组中的数据变成键值对结构(这里数组和obj会互相引用,这是算法实现的重点)

  map[list[I][idKey]]=list[I];

  }

  //构建一个树形数组

  for(设I=0;我leni ) {

  let item parid=list[I][parid key];

  //顶级节点

  if(itemParId===parId) {

  result . push(list[I]);

  继续;

  }

  //孤立节点,丢弃(其父节点不存在)

  如果(!map[itemParId]){

  继续;

  }

  //将当前节点插入到父节点的子节点中(因为是引用数据类型,如果obj中的节点发生变化,result中对应的节点也会相应变化)

  if(映射[itemParId].儿童){

  map[item parid]. children . push(list[I]);

  }否则{

  映射[itemParId]。children=[list[I]];

  }

  }

  返回结果;

  }

  

其他

  除了以上方法,还有很多优化技术,但我在项目中并不经常使用。

  冻结对象(以避免不必要的响应数据变得有响应)

  长列表呈现-批量呈现

  长列表渲染-动态渲染(vue-virtual-scroller)

  .

  

首屏/体积优化

  在我的项目中,首屏优化有以下几个优化方向。

  卷

  代码分段

  网络

  

体积优化

  压缩代码:webpack和vite的生产环境会默认压缩你的代码,一般不需要特殊处理。webpack也可以通过相应的压缩插件手动实现。

  取消源映射:您可以检查您的打包产品中是否有. map文件。如果有,您可以将source-map的值设置为false或empty来关闭代码映射(这会占用很大的空间)。

  启用gizp压缩:这需要开启服务器允许gizp传输,否则启用也没用(webpack有对应的gzip压缩插件,不同版本的webpack压缩插件可能不一样,建议先去官网查询)

  

代码分割

  代码分段的作用是将封装好的产品分成小的产品,这些产品依赖于esModule。所以当你使用import()函数导入一个文件或者依赖项的时候,这个文件或者依赖项会被单独打包成一个小产品。惰性加载和异步组件都使用这个原则。

  惰性路线加载

  异步组件

  对于UI库,我一般不采用按需加载组件的方式,而是更喜欢引入CDN的方式来优化。

  

网络

  CDN:首先是上面提到的CDN介绍。在开发阶段使用本地库,通过配置打包的外部扩展消除了这些依赖性。然后通过CDN在html文件中介绍它们。

  服务器:HTTP 2比较成熟;有了上述CDN的引入,我们可以利用HTTP2对网站的服务器推送功能,让浏览器提前加载这些CDN等文件。

  打开gzip:这个上面已经提到了。原理是当客户端和服务器都支持gzip传输时,服务器会先发送gzip压缩的文件,然后客户端接收并解压。

  打开缓存:一般情况下,我使用协商缓存,但这并不适用于所有情况。比如使用服务器推送的文件,不能随意修改文件名。所以我一般会固定主制作文件的文件名。

  这就是这篇关于22个Vue优化技术(实际项目)的文章。更多相关的Vue优化技术,请搜索我们之前的文章或者继续浏览下面的相关文章。希望大家以后能多多支持我们!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: