2021-03-03 React原理解析02

2021-03-03 React原理解析02

协调-reconciliation

设计动力
调用React的render()方法会创建一颗由React元素组成的树,在下一次state、props或context更新时候,相同的render()方法会返回一颗不同的树。React需要基于这两颗树之间的差别来判断如何有效的更新UI以保证当前UI与最新的树保持同步

React提出了一套O(n)-n是树中元素的数量,启发式算法(diff算法):
1、两个不同类型的元素会产生出不同的树
2、开发者可以通过keyprop属性来暗示哪些子元素在不同的渲染下能保持稳定

diff算法-算法复杂度O(n)
diff的策略:
1、同级比较,Web UI中DOM节点跨层级的移动操作特别少,可以忽略不计
2、拥有不同类型的两个组件将会生成不同的树形结构
例如:div->p,CompA->CompB
3、开发者可以通过keyprop属性来暗示哪些子元素在不同的渲染下能保持稳定

diff过程
对比两个虚拟dom时会有三种操作:删除、替换和更新
vnode是现在的虚拟dom,newVnode是新虚拟dom
删除:newVnode不存在时
替换:vnode和newVnode类型不同或key不同时
更新:有相同类型和key时,但vnode和newVnode不同时

fiber

为什么需要fiber

1、对于大型项目,组件树会很大,这个时候递归遍历的成本就会很高,会造成主线程被持续占用,结果就是主线程上的布局、动画等周期性任务就无法立即得到处理,造成视觉上的卡顿,影响用户体验

2、任务分解就是解决上面的问题

3、增量渲染(把渲染任务拆分成块,匀到多帧)

4、更新时能够暂停,终止,复用渲染任务

5、给不同的类型的更新赋予优先级

6、并发方面的基础能力

7、更流畅

什么是fiber
fiber是指组件上将要完成或者已经完成的任务,每个组件可以一个或者多个fiber,它的数据结构类似于链表,有指针指向,表示vnode节点
fiber

实现fiber

window.requestIdleCallback(callback[, options])
此方法将在浏览器的空闲时段内调用函数队列。这使得开发者能够在事件循环上执行后台和优先级工作,而不会影响延迟关键事件,如动画和输入响应。函数一般会按先进先调用的顺序执行,然而,如果回调函数指定了执行超时时间timeout,则有可能为了在超时前执行函数而打乱顺序

可以在空闲回调函数中调用requestIdleCallback(),以便在下一次通过事件循环之前调度另一个回调

Fiber是React 16中新的协调引擎,它的主要目的是使Virtual DOM可以进行增量渲染
一个更新过程可能会被打断,所以React Fiber一个更新过程被分为两个阶段:
第一个阶段:Reconciliation Phase
第二个阶段:Commit Phase

有fiber的react-dom.js文件

/**
 * vnode 虚拟DOM
 * node 真实DOM
 */

// 根节点 fiber
let wipRoot = null;
function render(vnode, container) {
   
  /* console.log("vnode", vnode);
  // vnode->node
  const node = createNode(vnode);
  // node 插入到container中
  container.appendChild(node); */

  wipRoot = {
   
    type: "div",
    props: {
    children: {
    ...vnode } },
    stateNode: container
  };

  nextUnitWork = wipRoot;
}

function isString(str) {
   
  return typeof str === "string";
}

// 根据vnode,生成node
function createNode(workInProgress) {
   
  let node = document.createElement(workInProgress.type);
  updateNode(node, workInProgress.props);

  return node;
}

// 更新属性
function updateNode(node, nextVal) {
   
  Object.keys(nextVal)
    // .filter(k => k !== "children")
    .forEach(k => {
   
      
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值