React与Vue都遵循组件化思想,它们把注意力放在UI层,将页面分成一些细块,这些块就是组件,组件之间的组合嵌套就形成最后的网页界面。
所以在开发时都有相同的套路,比如都有父子组件传递, 都有数据状态管理、前端路由、插槽等。
Vue与React都使用了 Virtual DOM + Diff算法, 不管是Vue的Template模板+options api 写法, 还是React的Class或者Function写法,最后都是生成render函数,而render函数执行返回VNode(虚拟DOM的数据结构,本质上是棵树)。
当每一次UI更新时,总会根据render重新生成最新的VNode,然后跟以前缓存起来老的VNode进行比对,再使用Diff算法(框架核心)去真正更新真实DOM(虚拟DOM是JS对象结构,同样在JS引擎中,而真实DOM在浏览器渲染引擎中,所以操作虚拟DOM比操作真实DOM开销要小的多)
======================================================================
React推荐的做法是JSX + inline style, 也就是把 HTML 和 CSS 全都写进 JavaScript 中,即 all in js;
Vue 推荐的做法是 template 的单文件组件格式(简单易懂,从传统前端转过来易于理解),即 html,css,JS 写在同一个文件(vue也支持JSX写法)
这个差异一定程度上也是由于二者核心思想不同而导致的。
传统Diff算法是循环递归每一个节点:
传统diff
如上图所示,从左侧a节点依次进行对比:a->d、a->e、a->b、a->a、a->c, 剩下的其他节点也是与右侧树每个节点进行对比。
将两颗树中所有的节点一一对比需要O(n²)的复杂度,在对比过程中发现旧节点在新的树中未找到,那么就需要把旧节点删除,删除一棵树的一个节点(找到一个合适的节点放到被删除的位置)的时间复杂度为O(n),同理添加新节点的复杂度也是O(n),合起来diff两个树的复杂度就是O(n³)
传统Diff算法复杂度太高, vue2.x加入了 Virtual Dom和react拥有相同的diff优化原则(将算法复杂度降为O(n))。
两者流程思路上是类似的:
-
不同的组件产生不同的 DOM 结构。当type不相同时,对应DOM操作就是直接销毁老的DOM,创建新的DOM。
-
同一层次的一组子节点,可以通过唯一的 key 区分。
![
](https://img-blog.csdnimg.cn/2097b18d5e0a449cb4eccf6bbed92b52.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDczMDg5Nw==,size_16,color_FFFFFF,t_70)
React的Diff算法核心实现
1.react首先对新集合进行遍历,for( name in nextChildren)。
2.通过唯一key来判断老集合中是否存在相同的节点。如果没有的话创建
3.如果有的话,if (preChild === nextChild )
-
会将节点在新集合中的位置和在老集合中lastIndex进行比较
-
如果if (child._mountIndex < lastIndex) 进行移动操作,否则不进行移动操作。
-
如果遍历的过程中,发现在新集合中没有,但在老集合中有的节点,会进行删除操作
Vue的Diff算法核心实现
updateChildren是vue diff的核心, 过程可以概括为:
前端面试题汇总
JavaScript
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
性能
linux
前端资料汇总