什么是 MVVM ?
react VUE angular
作为现代前端框架,有如下 4 个共有的特点:
接下来我们来重点对比一下 Vue 和 React 这两个框架的异同。
Vue 使用的是模板进行描述
React 使用的是 JSX 进行描述
不同的描述方式体现了两个团队不同的设计哲学。
React 团队认为,UI(HTML)本质上和逻辑(JS)存在耦合部分。作为前端开发工程师,JS 是用得最多的,因此它们考虑屏蔽 HTML,全部使用 JS 来描述 UI,这样子就可以让 UI 和 逻辑配合更紧密。因此他们设计出了 JSX
出发的角度是从前端出发的。
而模板刚好相反,是从后端的角度出发的。本质上是扩展了 HTML,在 HTML 中加入了相关逻辑的语法。
总结一下:
关于虚拟 DOM,React 团队官方的定时是描述真实 DOM 的一种方式。虚拟 DOM 是一种理念,实现的方式可以是多种多样的,只要你能够通过一种方式来描述真实 DOM,那么就是虚拟 DOM 的一种实现方案。
一说到虚拟 DOM,有人就会误认为虚拟 DOM 一定比原生操作 DOM 快,这种认识也是错的。
假设我就是单纯的创建一个 DOM:
let newP = document.createElement("p");
document.body.appendChild(newP);
这里的话,原生 DOM 的方式一定是比虚拟 DOM 更快的。因为即便是虚拟 DOM,最终也是要去操作真实的 DOM。
根据 React 团队的研究,大家平时在操作 DOM 的时候,比起使用原生的 API 去操作 DOM,更喜欢使用 innerHTML
document.body.innerHTML = `
asdasdasd
`;
那么此时,使用 innerHTML 就涉及到两个层面的计算
innerHTML | 虚拟 DOM | |
---|---|---|
JS 层面 | 解析字符串 | 创建 JS 对象 |
DOM 层面 | 创建对应的 DOM 节点 | 创建对应的 DOM 节点 |
因此可以看出,在第一次创建 DOM 节点的时候,虚拟 DOM 和传统的 innerHTML 的方式,至少都有两个层面的计算。
虚拟 DOM 真正发挥威力的时候,是在更新的时候。innerHTML 需要重新赋值,重新赋值意味着之前创建的 DOM 节点全部销毁。但是虚拟 DOM 会通过 diff 算法只更新必要的 DOM 节点
innerHTML | 虚拟 DOM | |
---|---|---|
JS 层面 | 解析字符串 | 创建 JS 对象 |
DOM 层面 | 销毁原来所有的 DOM | 修改必要的 DOM 节点 |
DOM 层面 | 创建对应的 DOM 节点 |
虚拟 DOM 还有一个好处?
多平台渲染的抽象能力。虚拟 DOM 可以对接不同的宿主环境,实现一个框架,多端渲染。
React 为什么要从以前的 Stack 架构改为 Fiber 架构 ?
Vue 是否需要 Fiber 架构 ?
要想把这两个问题搞清楚,首先需要搞清楚 Vue 和 React 设计上面的区别。
React 是否是响应式?Vue 是否是响应式 ?
React 不是响应式设计,而 Vue 是响应式设计,这意味 React 中当状态发生改变后,React 不知道是哪个改变了,需要通过 diff 算法计算后才知道。而 Vue 是响应式的,意味着一旦有数据发生变化,Vue 是知道的。
正因为这两种选择的不同,导致了两种框架在后面的发展中产生了巨大的区别。
React 这种设计,每次需要计算整颗虚拟 DOM,这个是属于 JS 层面的计算,虽然速度很快,但是一旦你的虚拟 DOM 数的体量很大,还是会消耗很长的时间。这意味浏览器本来要绘制下一帧了,但是你还在执行 JS,又不能打断。
从 React16 开始,官方引入了 Fiber 的概念,使用链表的方式来描述 UI,之所以采用链表,是因为中途能够打断。
官方两种架构的对比示例:https://claudiopro.github.io/react-fiber-vs-stack-demo/
Vue 不需要 Fiber 架构。因为 Vue 不存在像 React 一样要计算整颗虚拟 DOM 树这种要消耗大量时间的计算。Vue 是响应式的,Vue 本身也遇到了自身的瓶颈,那就是 watcher 太多了。
Vue 的解决方案就是引入虚拟 DOM,将虚拟 DOM 和响应式结合了起来,也就是改变了响应式的粒度。