vue - 常见的性能优化

这篇具有很好参考价值的文章主要介绍了vue - 常见的性能优化。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

vue - 常见的性能优化,vue.js,性能优化,javascript

vue使用中常见的性能优化


1, v-for 遍历避免同时使用 v-if

在 Vue2 中 v-for 优先级更高,所以编译过程中会把列表元素全部遍历生成虚拟 DOM,再来通过 v-if 判断符合条件的才渲染,就会有多余的逻辑判断和造成性能的浪费,因为我们希望的是不符合条件的虚拟 DOM都不要生成;

1,为了过滤一个列表中的项目 (比如 v-for="user in users" v-if="user.isActive")。在这种情形下,可以将 users 替换为一个计算属性或者方法 (比如 activeUsers),让其返回过滤后的列表;

<ul>
  <li
    v-for="user in activeUsers"
    :key="user.id"
  >
    {{ user.name }}
  </li>
</ul>

methods:{
	// 方法
	activeUsers(){
		//在这里面处理需要显示的数据  然后返回筛选过的列表
	}
}

2,为了避免渲染本应该被隐藏的列表 (比如 v-for="user in users" v-if="shouldShowUsers")。这种情形下,请将 v-if 移动至容器元素上 (比如 ul、ol)。

<ul v-if="shouldShowUsers">
  <li
    v-for="user in users"
    :key="user.id"
  >
    {{ user.name }}
  </li>
</ul>

在 Vue3 中 v-if 的优先级更高,就意味着当判断条件是 v-for 遍历的列表中的属性的话,v-if 是拿不到的;

注意:永远不要把 v-if 和 v-for 同时用在同一个元素上。

2, 如果需要使用v-for给每项元素绑定事件时 可以使用事件代理**

事件代理的本质就是利用事件冒泡到父元素的特性。这样就可以不用在循环的节点上每一个都加事件了;如下:

在父元素ul上面添加点击事件,如过需要传参的话 只需要添加自定义属性即可,比如下面的 id属性

  <!--  使用事件委托进行处理和传参 添加自定义属性id -->
    <ul class="weekdays" @click="debounce($event)">
      <li v-for="(item, index) in dayList" :key="index" :id="index" >{{ item.day }}</li>
    </ul>

	// 事件委托处理
    debounce(event) {
      if (event.target && event.target.nodeName == "LI") {
        // 现在就可以拿到当前的节点 所以就能拿到里面的属性和数据
          console.log("我点击的是:", event.target);
      }
    },

事件代理好处有2 个
1,将事件处理程序代理到父节点,减少内存占用率;
2,动态生成子节点时能自动绑定事件处理程序到父节点;

3, 一些数据不做响应式

一些数据不做响应式 比如会员列表、商品列表之类的,只是纯粹的数据展示,不会有任何动态改变的场景下,就不需要对数据做响应化处理,可以大大提升渲染速度;

可以使用 Object.freeze() 方法冻结一个对象,该方法冻结的对象不能被修改;即不能向这个对象添加新属性,不能删除已有属性,不能修改该对象已有属性的可枚举性、可配置性、可写性,以及不能修改已有属性的值,以及该对象的原型也不能被修改;

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

Vue2 的响应式源码地址:src/core/observer/index.js - 144行 是这样的:

export function defineReactive (...){
	// getOwnPropertyDescriptor 返回指定对象上一个自有属性对应的属性描述符
	// 也就是直接赋予该对象的属性,不需要从原型链上进行查找的属性
    const property = Object.getOwnPropertyDescriptor(obj, key)
    
	判断configurable``false`不做处理
    if (property && property.configurable === false) {
        return
    }
    ...
}

可以看到一开始就判断 configurablefalse 的直接返回不做响应式处理;

configurable``false` 表示这个属性是不能被修改的,而冻结的对象的 `configurable` 就是为 `false

这是vue正常定义在data里面的数据,会自动把下面的所有属性都添加get和set属性,有多少就添加多少:

vue - 常见的性能优化,vue.js,性能优化,javascript

开始冻结对象

freList是请求后端的列表数据;

  created() {
    this.dayList = Object.freeze(freList)
    console.log("daylist:",this.dayList);
  },

可以看出已经没有get和set属性了,但同时这些数据也不具备响应式了;

vue - 常见的性能优化,vue.js,性能优化,javascript

4,一些页面采用keep-alive缓存组件

比如在表单输入页面进入下一步后,再返回上一步到表单页时要保留表单输入的内容、比如在列表页>详情页>列表页,这样来回跳转的场景等;

基础使用:

	如果需要缓存整个项目,则如下设置(直接包裹根router-view即可)<keep-alive>
    	<router-view> </router-view>
	</keep-alive>

	缓存部分页面或者组件,使用route.meta属性
	<keep-alive>
    	<router-view v-if="$route.meta.keepAlive"></router-view>
	</keep-alive>
    	<router-view v-if="!$route.meta.keepAlive"></router-view>


	注:<keep-alive> 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。
	<keep-alive>
    	<component :is="view"></component>
	</keep-alive> 

注意: 配置了keepAlive的页面,在再次进入时不会重新渲染(第一次进来时会触发所有钩子函数),该页面内的组件同理不会再次渲染。

而这可能会导致该组件内的相关操作(那些每次都需要重新渲染页面的操作:如父子组件间的传值)不再生效。 这一点可能会导致一些莫名其妙而又无从查证的bug;

vue2.1.0 新增了include,exclude俩个属性,允许组件有条件的缓存。二者都可以用逗号分隔字符串、正则表达式或一个数组来表示。

    <!-- 逗号分隔字符串 -->
    <keep-alive include="a,b">
        <component :is="view"></component>
    </keep-alive>
 
    <!-- 正则表达式 (需要 `v-bind`绑定) -->
	<keep-alive :include="/a|b/">
    	<component :is="view"></component>
	</keep-alive>
 
    <!-- 数组 (需要 `v-bind`绑定) -->
	<keep-alive :include="['a', 'b']">
    	<component :is="view"></component>
	</keep-alive>

注:匹配首先检查组件自身的 name 选项,如果 name 选项不可用,则匹配它的局部注册名称 (父组件 components 选项的键值)。匿名组件不能被匹配。

动态判断,使用v-bind:include

<keep-alive :include="includedComponents">
    <router-view></router-view>
</keep-alive>

includedComponents动态设置即可  

使用beforeRouteLeave或者afterEach中进行拦截处理

如在项目在Category组件中的设置:
beforeRouteLeave(to,from,next){
    if(to.name=='DemoIndex'){
        if(!from.meta.keepAlive){
            from.meta.keepAlive=true
        }
        next()
    }else{
        from.meta.keepAlive=false
        to.meta.keepAlive=false
        next()
    }
},
在beforeRouteLeave中to.name根据具体的路由进行动态缓存设置

使用keepAlive后生命周期变化(重要):

首次进入缓存页面:beforeRouteEnter --> created --> mounted --> activated --> deactivated
再次进入缓存页面:beforeRouteEnter --> activated --> deactivated

注:
1、这里的activated非常有用,因为页面被缓存时,created,mounted等生命周期均失效,你若想进行一些操作,那么可以在activated内完成(下面会举个栗子:列表页回到上次浏览位置)
2、activated keep-alive组件激活时调用,该钩子在服务器端渲染期间不被调用。
3、deactivated keep-alive组件停用时调用,该钩子在服务端渲染期间不被调用。

5,第三方UI库按需导入

比如 vantUi, element-ui库的按需引入;见这篇文章

6,列表数据的懒加载 上滑加载分页数据

列表数据的懒加载滚动条上划到底时开始请求下一页的数据,尽量配合防抖函数使用,防止一瞬间请求的次数太多。

如下代码

这边我用的是vue3写的,vue2只是获取节点的方式不一样,其他都一样的;

onMounted(() => {
   // 获取滚动容器的节点
  let containerEle = showContentEl.value;
  if (!containerEle) return;
  
  // 监听滚动条
  containerEle.addEventListener("scroll", function () {
    const clientHeight = containerEle.clientHeight;
    const scrollTop = parseInt(containerEle.scrollTop);
    const scrollHeight = containerEle.scrollHeight;
    // 判断是否滚动条是否滚动到底  (-1是为了控制误差)
    if (clientHeight + scrollTop >= scrollHeight - 1) {
      // 开始防抖请求数据
      debounceLoadMaterialList();
    }
  });
});

<template>
  <div class="container">
    <div class="list">
      	展示的列表数据
    </div>
  </div>
</template>

设置接口防抖:

import * as _ from "lodash";
// 设置接口防抖
const debounceLoadMaterialList = _.debounce(loadMaterialList, 500);

7,变量本地化

简单说就是把会多次引用的变量保存起来,因为每次访问 this.xx 的时候,由于是响应式对象,所以每次都会触发 getter,然后执行依赖收集的相关代码,如果使用变量次数越多,性能自然就越差;

从需求上说在一个函数里一个变量执行一次依赖收集就够了,可是很多人习惯性的在项目中大量写 this.xx,而忽略了 this.xx 背后做的事,就会导致性能问题了;

比如下面vue2的例子

<template>
  <div :style="{ opacity: number / 100 }"> {{ result }}</div>
</template>
<script>
import { someThing } from '@/utils'
export default {
  props: ['number'],
  computed: {
    base () { return 100 },
    result () {
    
      let base = this.base, number = this.number // 保存起来  -- 变量本地化
      for (let i = 0; i < 1000; i++) {
        number += someThing(base) // 避免频繁引用 this.xx
      }
      return number
    }
  }
}
</script>

8,事件的销毁

Vue 组件销毁时,会自动解绑它的全部指令及事件监听器,但是仅限于组件本身的事件;

而对于定时器addEventListener 注册的监听器等,就需要在组件销毁的生命周期钩子中手动销毁或解绑,以避免内存泄露;文章来源地址https://www.toymoban.com/news/detail-579690.html

<script>
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)
    }
}
</script>

到了这里,关于vue - 常见的性能优化的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • [javascript核心-08] V8 内存管理机制及性能优化

    V8 本身也是程序,它本身也会申请内存,它申请的内存称为常驻内存,而它又将内存分为堆和栈 栈内存介绍 栈用于存放JS 中的基本类型和引用类型指针 栈空间是连续的,增加删除只需要移动指针,操作速度很快 栈空间是有限的,若超出栈空间内存,会抛出栈空间溢出错误

    2024年02月16日
    浏览(62)
  • 常见JVM参数配置和GC性能优化

    常见的JVM参数配置 垃圾回收统计信息 -XX:+PrintGC     打印GC简要信息 -XX:+PrintGCDetails打印GC的详细信息 -XX:+PrintGCTimeStamps打印CG发生的时间戳 -Xloggc:log/gc.log 指定GC log的位置,以文件输出 -XX:+PrintHeapAtGC 每一次GC前和GC后,都打印堆信息。 堆设置 -Xms:初始堆大,最小堆 -Xmx:最大

    2024年02月16日
    浏览(43)
  • 【Android常见问题(五)】- Flutter项目性能优化

    项目迭代开发一定程度后,性能优化是重中之重,其中包括了包体积,UI 渲染、交互等多个方面。 通过 Flutter 应用的混淆为入口,我们主要探讨了UI 渲染的优化。 其中就会涉及到一个非常关健的概念 ——「FPS,Frame Per Second」即「每秒展示帧数」,它代表了应用的流畅度。

    2024年02月15日
    浏览(53)
  • 前端性能优化的利器 ——— 浅谈JavaScript中的防抖和节流

    防抖和节流函数是工作中两种常用的前端性能优化函数,今天我就来总结一下什么是防抖和节流,并详细说明一下如何在工作中应用防抖和节流函数 在 JavaScript 中,防抖(debounce)和节流(throttle)是用来限制函数执行频率的两种常见技术。 防抖(debounce) 是指在某个时间段

    2024年02月14日
    浏览(51)
  • JavaScript中的数据缓存与内存泄露:解密前端性能优化与代码健康

    ​🌈个人主页:前端青山 🔥系列专栏:JavaScript篇 🔖 人终将被年少不可得之物困其一生 依旧 青山 ,本期给大家带来JavaScript篇专栏内容:JavaScript-数据缓存与内存泄露 目录 说说你对事件循环的理解 一、是什么 二、宏任务与微任务 微任务 宏任务 三、async与await async await 四、

    2024年02月03日
    浏览(76)
  • RK3568平台开发系列讲解(调试篇)常见的性能优化手段

    🚀返回专栏总目录 沉淀、分享、成长#

    2023年04月11日
    浏览(85)
  • 一份Node.js性能优化技巧指南

    你是一个踏入后端开发领域的前端爱好者吗?🤔 准备好迎接在Node.js错综复杂的景观中惊险刺激的旅程吧!🎢 在这个探险中,我们将探索后端的无数奇迹,从使用Node.js框架快速创建自己的后端,到应对性能分析、测试,深入内存管理。💻🔍 加入我们,揭开C++插件的奥秘,征服子进程

    2024年02月21日
    浏览(47)
  • 极致性能优化:前端SSR渲染利器Qwik.js

    前端性能已成为网站和应用成功的关键要素之一。用户期望快速加载的页面和流畅的交互,而前端框架的选择对于实现这些目标至关重要。然而,传统的前端框架在某些情况下可能面临性能挑战且存在技术壁垒。 在这个充满挑战的背景下,我们引入了 Qwik.js 框架。Qwik.js 不仅

    2024年02月05日
    浏览(67)
  • Node.js性能优化:实用技巧和最佳实践

    Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境,广泛用于构建快速的、可扩展的网络应用。尽管 Node.js 已经为处理大量并发连接提供了强大的性能,但在实际开发中仍然需要采取一些策略来优化性能和提升应用响应速度。以下是一些实用的技巧和最佳实践,可以帮助开发

    2024年04月17日
    浏览(43)
  • 【前端八股文】浏览器系列:性能优化——HTML、CSS、JS、渲染优化

    本系列目录:【前端八股文】目录总结 是以《代码随想录》八股文为主的笔记。详情参考在文末。 代码随想录的博客_CSDN博客-leecode题解,ACM题目讲解,代码随想录领域博主 性能优化,从以下几个方面来进行。 避免HTML中直接写CSS viewport加速页面渲染 使用语义化标签 减少标签的

    2023年04月20日
    浏览(61)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包