图解React Diff算法及新架构Fiber

简介: 阿里云前端工程师靖鑫带来了React高阶组件在业务场景中的应用。首先从高阶组件的思想开始谈起,帮助我们灵活管理代码,介绍了简单的HOC示例、传递参数的HOC示例、反向继承HOC,进而讲述了HOC库recompose,然后通过图解重点说明了DOM DIFF算法,最后对新架构Fiber进行了简要介绍。

阿里云前端工程师靖鑫带来了React高阶组件在业务场景中的应用。首先从高阶组件的思想开始谈起,帮助我们灵活管理代码,介绍了简单的HOC示例、传递参数的HOC示例、反向继承HOC,进而讲述了HOC库recompose,然后通过图解重点说明了DOM DIFF算法,最后对新架构Fiber进行了简要介绍。


数十款阿里云产品限时折扣中,赶快点击这里,领券开始云上实践吧!

直播视频精彩回顾

以下是精彩视频内容整理:

什么是高阶组件?

所谓高级组件本质上就是一个函数,接收一个组件后返回另外一个新的组件,这么做的意图就是为了增强(enhance),比如装饰、增添行为、增添逻辑等,都可以放在高阶组件中,高阶组件是一种可以增强组件的能力。

最简单的HOC示例

ac076ff9347e966af26d740e77dddf1b73b4e5ba

如图所示,使用装饰器方式来使用,声明一个函数,定义一个高阶组件,给目标组件包裹一层样式。接收一个组件,返回一个函数式组件props,将props全部解构传递给wrappedcomponent,高阶组件一定不可以影响原来的业务。在此基础上,我们在外面增加一些能力,比如在被包裹的组件外围,由一个card的dom元素包裹在一起。

传递参数的HOC示例

808404938cfc12629b6e43a59ebda784e1820896

首先设置参数,生成特定的HOC,再传递给目标组件使用。定义一个stylefactory方法,返回高阶组件,而不是组件。在高阶组件的前一步做了一层处理,利用闭包思想,它的入参是classname,返回的高阶组件一直内嵌classname。

反向继承HOC

00c34027b89082d22c1b99b21cf504194b1b68bb

前两种高阶组件的特点是不会修改原来的组件,只是在上面包裹一些东西。而有时会更改渲染逻辑,比如当wrappedcomponent资源没有加载回来时,页面显示loading,加载完成后才会显示,这就需要更改显示逻辑。反向继承HOC返回的React组件继承了被传入的组件,既然继承了被传入组件,是不是所有方法都可以使用呢?比如在render方法中渲染出之前的内容,可以直接使用super.render(),我们可以在render方法中重新写一个render,这样原有内容就都展示不出来了,想展示原有内容只需要调用super.render()即可。所以它能够访问到的区域、权限更多,相比属性代理方式,它更像打入组织内部,对其进行修改。

 

脑洞大开的HOC库——recompose

Recompose有很多很多实用的库,下面为大家介绍几个常见场景应用。

e1ead119a750b3d7712a0957470a79c138e729da

第一个情景是展示哪一个。有些时候,你需要根据后端返回值来做决策,例如展示Loading组件,之前你可能会将这部分判断写在render方法里,现在你可以将它们抽离出来了,将判断逻辑提前拿出来,我们的组件尽可能都是函数组件,不需要额外维护状态。顺带也可以将生命周期等方法挪出来,用高阶组件lifecycle代替。

如图所示,高阶组件是一层层被包裹起来的,最里面为wrappedcomponent组件,外部包裹一层branch高阶组件,branch专门用来做条件判断的,根据某一个值去判断真假,如果是真就会直接加载loading组件传递给你的业务组件,如果是假就会把另外一个高阶组件传递给你的业务组件,我们不需要在render方法里做这个判断。然后将代码发起请求的方式拿到lifecycle中去做,lifecycle本身可以写一些生命周期方法,state修改完后传递到branch高阶组件中透传,最终到达业务组件。

674a0d435f9487252ef1dfc97771b894db352637

第二个情景是维护组件自身的State。我们经常会有Tab切换,选择第一个、选择第二个等,将高亮的加上classname,点击展开(收起)等与业务数据无关的状态需要维护,回想以前的代码,我们可能会使用setState,但有时侯state和setstate不是很方便,组件可能非常长,也可能与真实业务代码融合在一起,容易使开发者混淆逻辑。有了recompose,我们可以使用withState和withHandlers来避免手动setState的出现,将展示逻辑和UI进行分离。

7649af3712a0e32015dbd24ec346544dfd690121

第三个情景是组件嵌套。在实际项目中,我们会有多个地方使用到Modal组件,如果都重复一遍上述代码,boilerplate代码将非常多,为此,我们可以将它转变为一个高阶组件,与常规方式不同,我们本次使用recompose提供的HOC来组织我们的代码。

 

DOM DIFF算法简析

b433a32607d8b1a89fa0a44e9155ad7d94e4d8d1

DOM DIFF是react应用中的精华所在,DOM DIFF在使用时有一些约定如下:

1.         DOM节点跨层级的移动操作特别少,可以忽略不计(例如A原本和B平级,随后A变成B的子节点)

2.         拥有相同类的两个组件将会生成相似的树形结构,拥有不同类的两个组件将会生成不同的树形结构(A和B组件结构不一致)

3.         同一层级的一组子节点,它们可以通过uuid进行区分。

DIFF算法在执行时有三个维度,分别是Tree DIFF、Component DIFF和Element DIFF,执行时按顺序依次执行,它们的差异仅仅因为DIFF粒度不同、执行先后顺序不同。

315badd9651f8d79363b01a506e8531759d40bfe

Tree DIFF是对树的每一层进行遍历,如果某组件不存在了,则会直接销毁。如图所示,左边是旧属,右边是新属,第一层是R组件,一模一样,不会发生变化;第二层进入Component DIFF,同一类型组件继续比较下去,发现A组件没有,所以直接删掉A、B、C组件;继续第三层,重新创建A、B、C组件。

5fbd248ebec60d443606aa8e612047d371355a40

如图所示,第一层遍历完,进行第二层遍历时,D和G组件是不同类型的组件,不同类型组件直接进行替换,将D删掉,再将G重建。

27222d09d321b46faeadca9a82dff6164cfbac12

Element DIFF紧接着以上统一类型组件继续比较下去,常见类型就是列表。同一个列表由旧变新有三种行为,插入、移动和删除,它的比较策略是对于每一个列表指定key,先将所有列表遍历一遍,确定要新增和删除的,再确定需要移动的。如图所示,第一步将D删掉,第二步增加E,再次执行时A和B只需要移动位置即可。

 

React Fiber

7d1162dd65baaa56bf26b21d3b4b9bdf52ecdbab

React Fiber是react执行渲染时的一种新的调度策略,JavaScript是单线程的,一旦组件开始更新,主线程就一直被React控制,这个时候如果再次执行交互操作,就会卡顿。

React Fiber重构这种方式,渲染过程采用切片的方式,每执行一会儿,就歇一会儿。如果有优先级更高的任务到来以后呢,就会先去执行,降低页面发生卡顿的可能性,使得React对动画等实时性要求较高的场景体验更好。

文章部分配图来自此文章:https://zhuanlan.zhihu.com/p/20346379

本文由云栖志愿小组毛鹤整理,编辑百见

相关文章
|
负载均衡 算法 关系型数据库
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
本文聚焦 MySQL 集群架构中的负载均衡算法,阐述其重要性。详细介绍轮询、加权轮询、最少连接、加权最少连接、随机、源地址哈希等常用算法,分析各自优缺点及适用场景。并提供 Java 语言代码实现示例,助力直观理解。文章结构清晰,语言通俗易懂,对理解和应用负载均衡算法具有实用价值和参考价值。
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
|
前端开发 调度 UED
React 执行过程中 Fiber 的优先级是如何确定的?
【10月更文挑战第27天】React能够更加智能地管理任务的执行顺序,在保证用户交互体验的同时,充分利用系统资源,提高应用的整体性能和响应速度。
|
机器学习/深度学习 人工智能 搜索推荐
从零构建短视频推荐系统:双塔算法架构解析与代码实现
短视频推荐看似“读心”,实则依赖双塔推荐系统:用户塔与物品塔分别将行为与内容编码为向量,通过相似度匹配实现精准推送。本文解析其架构原理、技术实现与工程挑战,揭秘抖音等平台如何用AI抓住你的注意力。
3092 7
从零构建短视频推荐系统:双塔算法架构解析与代码实现
|
存储 前端开发 JavaScript
深入理解React Fiber架构及其性能优化
【10月更文挑战第5天】深入理解React Fiber架构及其性能优化
887 1
|
JavaScript 前端开发 算法
React技术栈-虚拟DOM和DOM diff算法
这篇文章介绍了React技术栈中的虚拟DOM和DOM diff算法,并通过一个实际案例展示了如何使用React组件和状态管理来实现动态更新UI。
399 2
|
机器学习/深度学习 运维 监控
实时异常检测实战:Flink+PAI 算法模型服务化架构设计
本文深入探讨了基于 Apache Flink 与阿里云 PAI 构建的实时异常检测系统。内容涵盖技术演进、架构设计、核心模块实现及金融、工业等多领域实战案例,解析流处理、模型服务化、状态管理等关键技术,并提供性能优化与高可用方案,助力企业打造高效智能的实时异常检测平台。
|
负载均衡 算法
架构学习:7种负载均衡算法策略
四层负载均衡包括数据链路层、网络层和应用层负载均衡。数据链路层通过修改MAC地址转发帧;网络层通过改变IP地址实现数据包转发;应用层有多种策略,如轮循、权重轮循、随机、权重随机、一致性哈希、响应速度和最少连接数均衡,确保请求合理分配到服务器,提升性能与稳定性。
3277 11
架构学习:7种负载均衡算法策略
|
机器学习/深度学习 人工智能 自然语言处理
AI训练师入行指南(三):机器学习算法和模型架构选择
从淘金到雕琢,将原始数据炼成智能珠宝!本文带您走进数字珠宝工坊,用算法工具打磨数据金砂。从基础的经典算法到精密的深度学习模型,结合电商、医疗、金融等场景实战,手把手教您选择合适工具,打造价值连城的智能应用。掌握AutoML改装套件与模型蒸馏术,让复杂问题迎刃而解。握紧算法刻刀,为数字世界雕刻文明!
647 6
|
机器学习/深度学习 算法 PyTorch
深度强化学习中SAC算法:数学原理、网络架构及其PyTorch实现
软演员-评论家算法(Soft Actor-Critic, SAC)是深度强化学习领域的重要进展,基于最大熵框架优化策略,在探索与利用之间实现动态平衡。SAC通过双Q网络设计和自适应温度参数,提升了训练稳定性和样本效率。本文详细解析了SAC的数学原理、网络架构及PyTorch实现,涵盖演员网络的动作采样与对数概率计算、评论家网络的Q值估计及其损失函数,并介绍了完整的SAC智能体实现流程。SAC在连续动作空间中表现出色,具有高样本效率和稳定的训练过程,适合实际应用场景。
6709 7
深度强化学习中SAC算法:数学原理、网络架构及其PyTorch实现
|
存储 监控 算法
公司监控上网软件架构:基于 C++ 链表算法的数据关联机制探讨
在数字化办公时代,公司监控上网软件成为企业管理网络资源和保障信息安全的关键工具。本文深入剖析C++中的链表数据结构及其在该软件中的应用。链表通过节点存储网络访问记录,具备高效插入、删除操作及节省内存的优势,助力企业实时追踪员工上网行为,提升运营效率并降低安全风险。示例代码展示了如何用C++实现链表记录上网行为,并模拟发送至服务器。链表为公司监控上网软件提供了灵活高效的数据管理方式,但实际开发还需考虑安全性、隐私保护等多方面因素。
424 0
公司监控上网软件架构:基于 C++ 链表算法的数据关联机制探讨