某课网高级前端进阶必修(自主打造高扩展的业务组件库云pan)

download:高级前端进阶必修:自主打造高扩展的业务组件库. .

都说“双端比较算法”,那么双端比较算法是什么样的呢?和React中的diff算法有什么不同?
要理解这一点,首先要了解React中的Diff算法,然后是Vue3中的Diff算法,最后说说Vue2中的Diff算法,从而比较两者的区别。
最后说一下为什么Vue中不需要使用光纤架构。
对官方分析做出反应
其实React为什么不用Vue的双端比较算法?React官方已经在源代码的评论里解释过了。让我们来看看React官方是怎么说的。

函数reconcileChildrenArray( returnFiber:纤维, currentFirstChild: Fiber | null, newChildren:数组, expirationTime: ExpirationTime, ):光纤|空值{ //这个算法不能通过从两端搜索来优化,因为我们 //在纤程上不要有反向指针。我想看看我们能走多远 //用那个型号。如果最终不值得权衡,我们可以 //以后再加。//即使是两端优化,我们也希望针对这种情况进行优化 //在很少更改的情况下,强行进行比较,而不是 //去拿地图。它想探索先走这条路 //仅向前模式,并且仅在我们注意到需要时才使用地图 //很多前瞻。这不像双端那样处理反转 //搜索但那很不寻常。此外,对于两端优化来说 //处理Iterables,我们需要复制整个集合。//在第一次迭代中,我们将遇到最坏的情况 //(将所有内容添加到地图中)对于每次插入/移动。//如果更改此代码,也要更新reconcileChildrenIterator() //使用相同的算法。 }

【某课网高级前端进阶必修(自主打造高扩展的业务组件库云pan)】复制代码
大概意思是:
React无法通过双端比较优化Diff算法是因为目前纤程上没有反向链表,想知道这个方案能坚持多久?如果当前模式不理想,那么可以添加双端比较算法。
即使是双端比较算法,我们也要对这种情况进行优化。我们要用Map这种数据结构方案来代替原来那种改动不大的暴力比较的方案。它的第一个搜索周期是通过仅向前模式(即,它仅从左向右搜索)。(第一个周期可能还没结束,还有节点没对比。)如果要继续在正向循环中搜索,就必须使用数据类型映射。(就目前单向链表的数据结构而言,如果采用的话),双端比较搜索算法很难控制其反向搜索,但确实是一个成功的算法。另外,双端比较算法的实现也在我们的工作迭代中。
第一次迭代,就凑合用这个烂方案吧。每次添加/移动时,我们都必须将所有数据添加到Map数据类型对象中。
“我们需要复制整套”,这句话,我知道每个字,但我不知道他想说什么,所以我不会翻译它。有大神知道吗?
本人水平有限,错漏在所难免。如有错漏,请指正。
虽然React官方已经分析过了,但是要想彻底搞清楚为什么,我们还需要详细了解React的Diff算法是什么样的。在了解React Diff算法之前,我们首先要了解什么是纤程,为什么在React中使用纤程?
纤维的结构
在React15之前,通过更新React的组件来创建虚拟DOM和Diff的过程是不间断的。如果组件树的级别需要深度更新,Diff的进程会非常占用浏览器的线程,而我们都知道浏览器执行JavaScript的线程和渲染真实DOM的线程是互斥的,也就是说,在同一时间,浏览器要么在执行JavaScript代码操作,要么在渲染页面。如果JavaScript代码运行太长,页面就会卡住。
基于以上原因,React团队在React16之后重写了整个架构,把原来数组结构的虚拟DOM改成了一种叫纤程的数据结构。基于这种纤程数据结构,原来的不间断更新过程可以变成异步中断更新。
Fiber的数据结构主要看起来是这样的,Fiber的一些属性用来保存与组件相关的信息。
功能纤维节点(
标签:工作标签,
pendingProps:混合, key: null | string, 模式:TypeOfMode, ) { //作为静态数据结构的属性 this.tag = tag this.key = key this.elementType = null this.type = null this.stateNode = null//用于连接其他纤程节点,形成纤程树。 this.return = null this.child = null this.sibling = null this . index = 0;this.ref = null//作为动态工作单元属性 this . pending props = pending props; this.memoizedProps = null this.updateQueue = null this.memoizedState = null this.dependencies = nullthis.mode = modethis . effect tag = no effect; this.nextEffect = nullthis.firstEffect = null this.lastEffect = null//调度优先级关联 this.lanes = NoLanes this.childLanes = NoLanes//在另一次更新中指向该纤程对应的纤程。 this.alternate = null } 复制代码 纤程主要由以下属性连接成树形结构数据,即纤程链表。 //指向父纤程节点 this.return = null //指向子纤程节点 this.child = null //指向右边的第一个同级纤程节点 this.sibling = null 复制代码 例如,以下组件结构: 函数App() { 返回(我是 牛仔) }

    推荐阅读