1. 数据发生变化后,通知页面更新的方式不同
- 在Vue框架下,如果数据变化了,框架会主动告诉你修改了哪些数据;
- 而React的数据变化后,我们只能通过新老数据的Diff计算来得知数据的变化
这两个解决方案都解决了数据变化后,如何通知页面更新的问题,并且迅速地获得了很高的占有率,但是它们都碰到了性能的瓶颈:
- 对于Vue来说,它的一个核心就是“响应式”,也就是数据变化后,会主动通知我们。响应式数据新增Watcher监听,本身就比较消耗性能,项目大了之后每个数据都有一个watcher会影响性能。
- 对于React的虚拟DOM的Diff计算逻辑来说,如果虚拟DOM数过于庞大,使得计算时间大于16.6ms,那么就可能造成性能的卡顿。
为了解决这种性能瓶颈,Vue和React走了不同的道路:
React为了突破性能瓶颈,借鉴了操作系统时间分片的概念,引入了Fiber架构。通俗来说,就是把整个虚拟DOM树微观化,变成链表,然后利用浏览器的空闲时间计算Diff。一旦浏览器有需求,我们可以把没计算完的任务放在一旁,把主进程控制权还给浏览器,等待浏览器下次空闲。这个架构虽然没有减少运算量,但是巧妙地利用空闲实现计算,解决了卡顿的问题。
Vue引入虚拟DOM,采用组件级别的划分方式来解决响应式数据过多的问题。对于Vue2来说,组件之间的变化,可以通过响应式来通知更新。组件内部的数据变化,则通过虚拟DOM去更新页面。这样就把响应式的监听器,控制在了组件级别,而虚拟DOM的量级,也控制在了组件的大小。组件内部是没有Watcher监听器的,而是通过虚拟DOM来更新,每个组件对应一个监听器,大大减小了监听器的数量。
2. 模板书写的方式不同
React 的世界里只有 JSX,最终 JSX 都会在 Compiler 那一层,也就是工程化那里编译成 JS 来执行,所以 React 最终拥有了全部 JS 的动态性,这也导致了 React 的 API 一直很少,只有 state、hooks、Component 几个概念,主要都是 JavaScript 本身的语法和特性。
而 Vue 的世界默认是 template,也就是语法是限定死的,比如 v-if 和 v-for 等语法。有了这些写法的规矩后,我们可以在上线前做很多优化。Vue 3 很优秀的一个点,就是在虚拟 DOM 的静态标记上做到了极致,让静态的部分越过虚拟 DOM 的计算,真正做到了按需更新,很好的提高了性能。