手把手教学,带你升级vue3.0(二)为什么vue3性能会比vue2.0好

编译优化

patch过程优化

Block tree

  • Vue2中的diff算法进行全量对比的,数据更新并触发重新渲染的粒度是组件级的,但是在组件内部依旧需要去遍历该组件内部的vNode树,比如我们需要去更新这个组件
<template>
  <div>
    <p>static text</p>
    <p>static text</p>
    <p>{{message}}</p>
    <p>static text</p>
    <p>static text</p>
  </div>
</template>

整个diff过程会将所有标签都遍历,但是只有第三个p标签是动态标签,所以这里很多的diff和遍历都是不需要的,这就会导致Vnode如果整个模块动态节点很少时,这些遍历都是性能的浪费,而对于上诉这个例子,只需要遍历绑定的动态message p标签即可

  • Vue3 通过编译阶段对静态模板的分析,编译生成Block tree,block tree的根节点记录该树的动态节点,直接跳过静态节点的对比。所以该处理不用深度遍历和广度遍历,在静态节点更多的情况下,其性能远远领先vue2的diff。

PatchFlag

静态标记
vue2在新旧树对比时,需要对比属性是否变化,内容是否变化等,而vue3会通过patchFlag标记这些节点类型、节点属性、节点内容等,在新旧树对比中只对比某一属性。

它与上次虚拟节点进行对比的时候,只对比带有静态标记的节点,并且可以通过flag得知当前节点需要对比的内容,如下图所示
在这里插入图片描述
vue3.0在创建虚拟DOM的时候,会根据DOM中的内容,会不会发生变化,来添加静态标记,因为<p>我是段落</p> 它是不会写死的,所以也不需要多浪费资源去对它进行对比,然后对会变化的<p>{{msg}}</p>就自动添加上静态标记,这里面的1 指的是文本的一个静态标记,flag它是一个枚举,因为会改变的有时候不止会有文本,也会有class,style。

静态提升(hoistStatic)

  • Vue2中无论元素是否参与更新,每次都会重新创建,然后再渲染
  • Vue3中对于不参与更新的元素(比如上文的<p>我是段落</p> ),会做静态提升(提升到全局变量里面),只会被创建一次,在渲染的时候直接复用即可。

事件侦听缓存(cacheHandlers)

vue2 onClick会被视为动态绑定,所以每次都会去追踪它的变化,但是因为是同一个函数。
所以vue3认为事件的处理一般是不会变化的,所以其对事件处理函数进行缓存。

//vue2
render(ctx){
	return createVNode('button',{
		onClick:function($event){
			ctx.count++
		}
	})
}

//vue3
render(ctx,_cache){
	return createVNode('button',{
		onClick:cache[0] || (cache[0] = ($event) => ctx.count++)
	})
}

源码体积优化

引入tree-shaking技术

依赖ES6模块语法的静态结构(即import和export)
通过编译阶段的静态分析,找到没有引用的模块并打上静态标记

如果在项目中如果没有引入transition、keepalive等组件,那么他们对应的代码就不会被打包,这样也间接的起到了减少项目引入vuejs包体积的目的

数据劫持优化

  • vue2是通过使用Object.defaultPrototype这个API来劫持数据的getter和setter,但这个API有一些缺陷,
    1、需要预先知道拦截的key是什么,所以并不能检测对象属性的新增和删除,即使提供了$set和$delete等方法,但是还是新增了使用负担
    2、如果遇到嵌套层级过多的对象,那么就需要对这个对象进行递归遍历,对每一层对象进行数据监听,如果定义的数据复杂,会对性能造成一定的影响

  • vue3使用的是Proxy去劫持整个对象,自然对对象的属性新增和删除都能检测到,不过需要注意的是,proxy不能监听到对象内部深层次的变化,因为vue3处理方式是在getter中去递归响应式,这样子的好处是真是访问到内部对象才会变成响应式,而不是无脑递归,这无疑很大程度提升了性能

语法方面

vue2 本质就是编写一个包含了描述组件选项的对象 我们成为option API ,按照data、methods、props、watch、computed选项分类,
如果处于比较小型的项目中,可能逻辑还是可以分清的,但是如果处于大型的项目中一个组件可能有多个逻辑关注点,非常分散,如果需要修改一个逻辑关注点的时候,就需要上下来回的切换代码,

vue3 提供了Componsition api

优化逻辑复用

当我们开发的项目比较复杂的时候,免不了需要抽离出来一些复用的代码,在vue2.x中我们通常会使用混入(mixins)去复用逻辑,举一个鼠标监听的例子,我们会编写如下代码。

const mousePositionMixin = {
  data() {
    return {
      x: 0,
      y: 0
    }
  },
  mounted() {
    window.addEventListener('mousemove', this.update)
  },
  destroyed() {
    window.removeEventListener('mousemove', this.update)
  },
  methods: {
    update(e) {
      this.x = e.pageX
      this.y = e.pageY
    }
  }
}
export default mousePositionMixin

然后在组件中使用:

<template>
  <div>
    Mouse position: x {{ x }} / y {{ y }}
  </div>
</template>
<script>
import mousePositionMixin from './mouse'
export default {
  mixins: [mousePositionMixin]
}
</script>

使用单个 mixin 似乎问题不大,但是当我们一个组件混入大量不同的 mixins 的时候,会存在两个非常明显的问题:命名冲突 和 数据来源不清晰。

  • 1、首先每个 mixin 都可以定义自己的 props、data,它们之间是无感的,所以很容易定义相同的变量,导致命名冲突。
  • 2、另外对组件而言,如果模板中使用不在当前组件中定义的变量,那么就会不太容易知道这些变量在哪里定义的,这就是数据来源不清晰。

Vue.js 3.0 设计的 Composition API,就很好地帮助我们解决了 mixins 的这两个问题。
在vuejs3.x中使用hook来解决

import { ref, onMounted, onUnmounted } from 'vue'
export default function useMousePosition() {
  const x = ref(0)
  const y = ref(0)
  const update = e => {
    x.value = e.pageX
    y.value = e.pageY
  }
  onMounted(() => {
    window.addEventListener('mousemove', update)
  })
  onUnmounted(() => {
    window.removeEventListener('mousemove', update)
  })
  return { x, y }
}

然后进行使用。

<template>
  <div>
    Mouse position: x {{ x }} / y {{ y }}
  </div>
</template>
<script>
  import useMousePosition from './mouse'
  export default {
    setup() {
      const { x, y } = useMousePosition()
      return { x, y }
    }
  }
</script>

我们可以看到,数据来源变得清晰了,即使去编写更多的hooks,也不会出现命名冲突的问题。
Componsition api除了在逻辑复用方面存在一些优势,也会有更好的类型支持,因为它们都是一些函数,在调用函数时,自然所有的类型就被推导出来了,不像 Options API 所有的东西使用 this。另外,Composition API 对 tree-shaking 友好,代码也更容易压缩。这里还需要说明的是,Composition API 属于 API 的增强,它并不是 Vue.js 3.0 组件开发的范式,如果你的组件足够简单,你还是可以使用 Options API。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要搭建Vue3.0项目的环境,您可以按照以下步骤进行操作: 1. 首先,确保您已经安装了Node.js。您可以在命令行中输入 "node -v" 来检查是否已安装Node.js。如果*** 升级Vue CLI到4.0版本。如果您之前已经安装了旧版本的Vue CLI,需要先卸载旧版本。您可以在全局命令行中运行 "cnpm uni -g vue-cli" 来删除旧版本。然后,您可以在全局命令行中运行 "cnpm i -g @vue/cli" 来安装Vue CLI的4.0版本。最后,您可以通过运行 "vue -V" 检查Vue CLI的版本号,确保已经成功安装了4.0版本。 3. 创建一个新的Vue项目。您可以使用命令行进入到您想要创建项目的目录中,然后运行 "vue create 项目名" 来创建一个新的Vue项目。根据提示选择您所需的特性和插件,然后等待项目创建完成。 4. 进入项目文件夹。在命令行中切换到您刚刚创建的项目文件夹中,使用 "cd 项目名" 命令。 5. 启动项目。在项目文件夹中运行 "npm run serve" 命令来启动项目。这将启动一个开发服务器,并在浏览器中打开项目。 通过按照以上步骤,您就可以成功搭建Vue3.0项目的环境,并开始进行开发了。如果您需要更详细的配置或使用Vue3.0进行接口封装,以及使用ant-design-vue进行后台管理系统的开发,可以参考相应的文档或教程进行进一步学习。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [手把手教你vue3.0项目搭建](https://blog.csdn.net/weixin_42762167/article/details/112216178)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [配置一个vue3.0项目的完整步骤](https://download.csdn.net/download/weixin_38629130/13200273)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值