核心理念:可变 vs 不可变

vue:响应式数据,数据变化,修改原数据,并对数据的变更进行拦截。从而实现响应数据变更;
模板语法范式
react: 推崇不可变数据,数据变化,根据变化生成新数据,对比新旧dom,得到变更。从而实现响应数据变更;
jsx范式

image.pngimage.png

使用特点

vue:简单好上手,依靠api, Vue通过模版语言限制了开发者的操作
譬如一些api:computed、watch、v-model、$nextTick; 基本靠api可以解决很多事;
react:api少基本是 render + 各种生命周期函数
15之后是,hook:函数式编程
特点:概念模型超级多,学习react会学习到很多概念。
譬如:函数式编程-代数效应、副作用、单向数据流; 调度
代码的按预期运行,靠开发者的心智模型:了解react的运行机制,依靠最佳实践来规范代码;

使用场景:
vue > react: 对于简单的逻辑,vue更适合;因为在api的限制下 很容易解决问题,也不会出什么代码差异;

react > vue: 当需要灵活度的时候,特别是依赖了 闭包等逻辑(更依靠js原生的逻辑能力,而不是data->dom的自动渲染能力)时,具体可看react-motion,在jsx里用闭包的典范,可以弄懂react这套jsx范式相比mvvm那套模板范式到底优越在哪里

性能瓶颈及优化处理:

1、vue 与 react更新时的diff对比——精准找到更新的那个组件区别:

对于Vue来说,使用模板让它有了很多优化的空间,配合响应式机制可以让Vue可以精确地进行节点更新
比如在一个父组件中更新state.childAProps,vue是准确知道是子组件A数据发生了变化,他就会去diff子组件A
Vue 用啥机制能知道是哪个子组件发生了变化的,
vue2.x是通过setter和getter准确知道更新哪里,——性能压力:watcher过多

优化1:vue2 watcher以组件为粒度 而不是data
Vue1 中的监听器过多,也会让性能雪崩,为了解决这个问题,Vue 选择了权衡:
以组件作为颗粒度,组件层面用响应式通知,组件内部通过 dom diff 计算
既控制了应用内部 Watcher 的数量,也控制了 dom diff 的量级。

image.png

优化2:vue3:通过静态标记 + 响应式 + 虚拟 dom 的方式,控制了 diff 的颗粒度,让 diff 的时间不会超过 16ms


react不知道是谁发生了变化,会diff所有子组件。——性能压力:diff时长
react是通过比较引用的方式来更新,所以导致了层层更新

React15 架构中,dom diff 的时间超过 16.6ms,就可能会让页面卡顿
react的diff是自上而下的,对此 React 交出的解决方案就是时间切片
把 diff 的任务按照元素拆开,利用浏览器的空闲时间去算 diff

image.png

image.png

2、性能优化:
Vue使用模板语法,可以在编译时对模板优化:模板是静态的,限制多的好处在于利于分析,静态模板编译分析可以有很大的优化空间;

React使用jsx:不好确定哪个部分是一定不会重新渲染的,使他在编译时优化方面先天不足
所以react的优化主要是在运行时;

raact运行时优化所做的努力:
1、React15实现了batchedUpdates(批量更新);
2、react15以后:Concurrent Mode(并发模式):实现一套可中断/恢复的更新机制。

  • 一套协程架构 —————— 即React16中实现的Fiber Reconciler(可以理解为react自己的Generator)
  • 基于协程架构的启发式更新算法

协程架构使更新可以在需要的时机被中断,这样浏览器就有时间完成样式布局与样式绘制,减少卡顿(掉帧)的出现。
当浏览器进入下一次事件循环,协程架构可以恢复中断或者抛弃之前的更新,重新开始新的更新流程。
启发式更新算法就是控制协程架构工作方式的算法

设计思路

image.png

运行时 vs 预编译

image.png

Vue :template
依然处于比较中庸的地位,在运行时和预编译取了一个很好地权衡,保留了虚拟 dom,通过响应式控制虚拟 dom 的颗粒度,在预编译里又做了足够多的性能优化,做到了按需更新
Vue3 通过在预编译阶阶段做静态标记的优化,做到了按需更新

  1. 纯静态的元素标记,直接越过 diff 阶段 比如

    hello

  2. 静态的属性也会标记,在 diff 的时候越过这个属性的判断
  3. 事件函数传递的时候回加上缓存
  4. v-if 和 v-for 内部通过 block+ 数组的方式维护动态元素

React:运行时。JSX
所谓运行时,在浏览器内存里进行的任务,React 的 Runtime 比较重一些,数据发生变化后,并没有直接去操作 dom,而是生成一个新的虚拟 dom,并且通过 diff 算法得出最小的操作行为,全部都是在运行时来做的

预编译的极端典型:svelte
重编译的框架,在上线之前经过通过工程化的方式做了预处理
基本上是一个 Compiler Framework,写的是模板和数据,经过处理后,基本解析成了原生的 dom 操作

参考资料

React 与 Vue 框架的设计思路大 PK【早早聊】