Vue.js 3.0 响应式 API 比 2.x 好在哪儿?

Hello,各位小伙伴,接下来的一段时间里,我会把我的课程《Vue.js 3.0 核心源码解析》中问题的答案陆续在我的公众号发布,由于课程的问题大多数都是开放性的问题,所以我的答案也不一定是标准的,仅供你参考喔。

本期的问题:为什么说 Vue.js 3 的响应式 API 实现和 Vue.js 2.x 相比性能要好,具体好在哪里呢?它又有哪些不足呢?

响应式实现方式

响应式原理是 Vue.js 的核心思想之一,它的本质是当数据变化后会自动执行某个函数。

响应式的实现基本都是靠数据劫持,在 Vue.js 2.x 中,是通过 Object.defineProperty API 劫持数据的变化,在数据被访问的时候收集依赖,然后在数据被修改的时候通知依赖更新。

而到了 Vue.js 3.0,作者使用 Proxy API 来劫持数据,并重写了响应式部分。

Proxy VS Object.defineProperty

那么,ProxyObject.defineProperty 有哪些区别呢?

从 API 上来看,Proxy 劫持的是整个对象,那么对于对象属性的新增、删除、修改自然都可以劫持到;而Object.defineProperty API 劫持的对象某一个属性的访问和修改,因此它不能监听对象属性新增和删除。

从兼容性上来看,Object.defineProperty 支持所有主流浏览器,并兼容 IE9+,而 Proxy 支持现代主流浏览器,但唯独不支持 IE,在国内 PC 端还没有完全放弃 IE 的大环境下,导致 Vue.js 3.0 的普及受到限制。

从性能上看,ProxyObject.defineProperty 要慢。没错,是慢喔,为了测试它们的性能差异,我特地写了一个测试 demo,放在了 GitHub 上 https://github.com/ustbhuangyi/Proxy-vs-DefineProperty,感兴趣的同学可以 clone 下来跑一下。

性能差异

既然 ProxyObject.defineProperty 慢,那么为何说 Vue.js 3.0 的响应式 API 实现和 Vue.js 2.x 相比性能要好呢?

其实这个性能好主要体现在初始化阶段。Vue.js 2.x 内部把某个对象变成响应式的时候,如果遇到对象的某个属性的值仍然是对象的时候,会递归把子对象也变成响应式。

到了 Vue.js 3.0,并不会在初始阶段递归响应式,而是在对象属性被访问的时候才递归执行下一步 reactive,这其实是一种延时定义子对象响应式的实现,在性能上会有较大的提升。

说到延时响应式,那么 Vue.js 2.x 也可以这么做吗,其实也是可以的,我对 Vue.js 2.x 的响应式源码部分做了修改,如下:

  Object.defineProperty(obj, key, {enumerable: true,configurable: true,get: function reactiveGetter() {const value = getter ? getter.call(obj) : vallet childOb = !shallow && observe(value)if (Dep.target) {dep.depend()if (childOb) {childOb.dep.depend()if (Array.isArray(value)) {dependArray(value)}}}return value}// ...})

改动很简单,就是把递归的 observe 放在了 getter 中执行。

改完后我跑了一下 Vue.js 的单元测试,发现只有几个测试没通过,但没通过的测试用例是因为我们改动的逻辑影响了这些测试用例原本的含义,但实际上并无本质的影响,因此在 Vue.js 2.x 中,把递归响应式的逻辑放在 getter 中也是可行的。

到这里你可能会问,如果延时响应式,那会不会每次访问数据的时候都要重新定义一次响应式呢,其实是不用的,在 Vue.js 2.x 中,在执行一次 observe 后,会把观察者对象 ob 保留在 value.__ob__ 属性中;而在 Vue.js 3.0 中,会用 reactiveMap 保留已定义的响应式对象,这样下一次就直接从缓存里拿到对应的值了,这就是典型的空间换时间的思想。

总结

所以就响应式的实现而言,Vue.js 3.0 比 Vue.js 2.x 在性能上的优势主要体现在初始化阶段,不需要递归把子对象定义成响应式。而 Proxy 本身并不比 Object.defineProperty 快,好处是在于可以直接对整个对象劫持,包括对象属性的新增和删除,劣势就是浏览器的兼容性不够好,而且没有合适的 polyfill。

我出这个题主要是希望你能做到以下两点:

  1. 从源码层面探索,了解 Vue.js 响应式的实现原理。

  2. 对比 Vue.js 2.x 和 Vue.js 3.0 在响应式实现上的差异。

要记住,分析和思考的过程远比答案重要。


最近组建了一个江西人的前端交流群,如果你也是江西人可以加我微信ruochuan12 拉你进群。


你好,我是若川,江西人~(点击蓝字了解我)历时一年只写了一个学习源码整体架构系列 有哪些必看的JS库:jQuery、underscore、lodash、sentry、vuex、axios、koa、redux

  1. 关注若川视野,回复"pdf" 领取优质前端书籍pdf,回复"1",可加群长期交流学习

  2. 我的博客地址:https://lxchuan12.gitee.io 欢迎收藏

  3. 觉得文章不错,可以 分享、点赞、在看 呀^_^另外欢迎留言交流~

小提醒:若川视野公众号面试、源码等文章合集在菜单栏中间【源码精选】按钮,欢迎点击阅读,也可以星标我的公众号,便于查找

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/276166.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

招聘.NET程序员

人才难找啊,顺便发个招聘启事。 西安瀚博科技有限公司招聘.NET程序员,有工作经验者优先 如有意向,请发邮件到 slzhanghiweb.cn 转载于:https://www.cnblogs.com/shengli/archive/2010/03/08/1680861.html

xml解析类

转载链接:http://zyan.cc/post/253 今天在PHP4环境下重新写一个接口程序,需要大量分析解析XML,PHP的xml_parse_into_struct()函数不能直接生成便于使用的数组,而SimpleXML扩展在PHP5中才支持,于是逛逛搜索引擎&#x…

jmeter学习指南之聚合报告

jmeter视频地址:https://edu.51cto.com/course/14305.html 上一篇文章中我们讲了Jmeter结果分析最常用的一个Listener查看结果树,今天接着讲另一个最常用的listener--聚合报告Aggregate Report。我们先来看看聚合报告中的主要名称的含意:Labe…

敏捷开发概述

敏捷方法强调适应性而非预见性。 目前列入敏捷方法的有: 軟件開發節奏,Software Development Rhythms 敏捷數據庫技術,AD/Agile Database Techniques 敏捷建模,AM/Agile Modeling 自適應軟件開發,ASD/Adaptive Softwar…

2021 整理的最全学习资源,送给每一个努力着的人

时间来到了 2021 年,新的一年有新的期待,而我亦有新的祝福如果说在过去的一年,经历太多,心酸、迷茫、焦虑、幸福、喜悦那么在 2021 年,希望你可以去过一种遇见自己的生活,恬淡、热情,喜欢自己而…

ubuntu+php环境下的Memcached 安装方法

转载链接:http://www.jb51.net/article/28887.htm Memcached是一套分散式的高速缓存系统,当初是Danga Interactive为了LiveJournal所发展。 目前被很多系统所使用,例如Flick、Twitter等。这是一套开放源代码软件,以BSD license授…

php移动签批源码_PHP让网站移动访问更加友好方法

PHP都是在服务器上处理的,所以当代码到达用户时,它只是HTML。基本上,用户从你的服务器请求你网站的一个页面,然后你的服务器运行所有的PHP并向用户发送PHP的结果。设备实际上从未看到或必须使用实际的PHP代码。这使得使用PHP完成的…

Chrome OS 设备或将允许用户自行选择 Linux 发行版

百度智能云 云生态狂欢季 热门云产品1折起>>> 谷歌去年宣布在 Chrome OS 上支持运行 Linux 应用,前不久又有消息称其将为运行这些 Linux 应用提供 GPU 加速支持,而现在,Chrome OS 似乎将在 Linux 的方向上更进一步,让 …

博文视点 OpenParty第11期:世界黑客大会那些事

博文视点 OpenParty第11期:世界黑客大会那些事 亲爱的读者朋友: 您好! 2009年,博文视点Open Party共举办8场,累计到场2000人次,影响力辐射近5000人次,真正实现了博文视点Open Party的初…

我从 Vuejs 中学到了什么——框架设计学问

框架设计远没有大家想的那么简单,并不是说只把功能开发完成,能用就算完事儿了,这里面还是有很多学问的。比如说,我们的框架应该给用户提供哪些构建产物?产物的模块格式如何?当用户没有以预期的方式使用框架…

CSS制作的32种图形效果[梯形|三角|椭圆|平行四边形|菱形|四分之一圆|旗帜]

转载链接:http://www.w3cplus.com/css/css-simple-shapes-cheat-sheet 前面在《纯CSS制作的图形效果》一文中介绍了十六种CSS画各种不同图形的方法。今天花了点时间将这方面的制作成一份清单,方便大家急用时有地方可查。别的不多说了,直接看代…

vue-cli新建的项目webpack设置涉及的大部分插件整理

portfinder 用来检测未占用的端口更多看这里: https://www.npmjs.com/package/portfinder webpack-merge 用来合并多个webpack设置,也可以合并对象更多看这里: https://www.npmjs.com/package/friendly-errors-webpack-plugin html-webpack-plugin 将html复制并插入…

yaml加配置文件后起不来_YAML配置文件管理资源

YAML是配置文件的格式,YAML文件中是由一些易读的字段和指令组成的。K8S使用YAML配置文件需要注意如下事项。定义配置时,指定最新稳定版API(当前最新稳定版是v1版本)。最新版本的API可以通过kubectl api-versions命令进行查看,命令如下所示。前…

html5/css3响应式布局介绍

转载链接:http://www.51xuediannao.com/htmlcss/htmlcssjq/694.html html5/css3响应式布局介绍 html5/css3响应式布局介绍及设计流程,利用css3的media query媒体查询功能。移动终端一般都是对css3支持比较好的高级浏览器不需要考虑响应式布局的媒体查询…

人际关系十大要诀

【一表人才】 所谓“一表人才”,就是说当你与陌生人第一次见面时给对方留下的第一印象,我们都知道第一印象很重要,要给对方留下好的印象,特别是要让对方在最短的时间记住你。那么我们自身的仪表、行为举止都很重要;我们…

MobX 上手指南,写 Vue 的感觉?

之前用 Redux 比较多,一直听说 Mobx 能让你体验到在 React 里面写 Vue 的感觉,今天打算尝试下 Mobx 是不是真的有写 Vue 的感觉。题外话在介绍 MobX 的用法之前,先说点题外话,我们可以看一下 MobX 的中文简介。在 MobX 的中文网站…

ansible中yaml语法应用

4、yaml语法应用 ansible的playbook编写是yaml语言编写,掌握yaml语法是编写playbook的必要条件,格式要求和Python相似,具体教程参考如下yaml语言教程 附上一个yaml文件转js格式文件链接在线免费yaml内容转json格式 4.1、 ansible中的yaml语法…

中兴a2018拆机图片_中兴天机拆机步骤详解【图文】

中兴天机上市时有两款,黑色和白色。黑色的缺点是外观过于传统,并不是很适合年轻人使用,但是其推出白色款却很好的解决了这个问题。中兴天机的整体性质与性价比完美的拼过了 小米 3等同时上线的手机产品。中兴天机价格在1799左右,小…

网络视频贴片广告全面推行第三方监测

视频网站优酷与国际调研机构尼尔森联合对外宣布:针对优酷视频贴片广告全面推行第三方监测。这是视频行业首次倡导广告投放数据透明化的一大举措。  近年来,网络视频已经成为广告主营销的一大选择。随着广告主投放额度不断加大,广告主对视频…

css3动画事件—webkitAnimationEnd

转载链接:http://www.jb51.net/css/72443.html 用css3的animation完成一个动画,当只有这个动画完成时才执行令一个事件,比如让动画保持在终止的状态或其他一些事件。我们该怎么办呢。 第一种方法: 用计时器,设定一个…