实现一个精简React -- 性能优化,减少不必要的计算(8)

在目前更新props的逻辑中,我们发现,如果更新一个子组件的话,会导致整个dom树都会更新,这样就造成了性能的浪费,所以我们只需要更新变化的子组件即可。

更新逻辑

旧的逻辑

update() 函数中,是将根节点重新赋值给nextUnitOfFier后重新启动 perfromFiberOfUnit ,创建dom,建立链表关系,对新旧dom树的props进行更新、删除、新建操作,最后重新挂载到根节点

优化后的逻辑

update() 函数中,将需要更新的组件赋值给nextUnitOfFier 后重新启动后面的逻辑,并且在下一个组件更新前终止。

按照优化逻辑,我们需要获取到开始点和结束点:

  • 开始点:当前更新的组件
  • 结束点:当前更新组件的sibling节点

代码实现

获取起始点

重新创建一个wipFiber参数用来表示当前更新的组件fiber

js 复制代码
let wipFiber = null
function updateFunctionComponent(fiber) {
    // 获取正在更新的组件
    wipFiber = fiber;
    const children = [fiber.type(fiber.props)];
    reconcileChildren(fiber, children);
}

但由于wipFiber是一个全局变量,会导致后面的组件参数覆盖之前的组件参数,所以可以采用闭包的方式来存下当前组件fiber。

将这个currentFiber赋值给wipRoot后,我们就获取到了开始点,然后赋值给nextUnitOfFier后启动更新。

js 复制代码
function update() {
    let currentFiber = wipFiber;

    return () => {
        wipRoot = {
            ...currentFiber,
            alternate: currentFiber,
        };

        nextUnitOfFier = wipRoot;
    };
}

获取结束点

在更新逻辑中,如果碰到结束点的话,就应该停止创建链表,将已更新的dom挂载到对应的节点上去,所以结束点应该在 workLoop 逻辑中,

当判断当前更新的fiber(wipRoot)的sibling与 perfromFiberOfUnit 返回的 nextUnitOfFier 的type相同则表示结束点

js 复制代码
function workLoop(idleDeadline) {
    let shouldYield = false;
    while (!shouldYield && nextUnitOfFier) {
        nextUnitOfFier = perfromFiberOfUnit(nextUnitOfFier);

        // 判断结束点
        if (wipRoot?.sibling?.type === nextUnitOfFier?.type) {
            nextUnitOfFier = undefined;
        }

        shouldYield = idleDeadline.timeRemaining() < 1;
    }

    // ...
}

给nextUnitOfFier赋值为undefined后结束更新vdom,开启挂载操作。

相关推荐
宇寒风暖10 分钟前
HTML嵌入CSS样式超详解(尊享)
前端·css·笔记·学习·html
秋天的一阵风14 分钟前
‌ES Module 都过十岁生日了,你还不了解它的运行原理吗?
前端·javascript·面试
FreeCultureBoy18 分钟前
本地运行LLM的实用指南
前端
二川bro35 分钟前
前端项目Axios封装Vue3详细教程(附源码)
前端
古柳_Deserts_X36 分钟前
看看 ManusAI 相关网站长啥样。通过「新词新站」思路挖到720K月访问、140K月访问的两个新站
前端·程序员·创业
Moment1 小时前
前端白屏检测SDK:从方案设计到原理实现的全方位讲解 ☺️☺️☺️
前端·javascript·面试
阿波次嘚1 小时前
关于在electron(Nodejs)中使用 Napi 的简单记录
前端·javascript·electron
咖啡虫1 小时前
解决 React 中的 Hydration Failed 错误
前端·javascript·react.js
贩卖纯净水.1 小时前
《React 属性与状态江湖:从验证到表单受控的实战探险》
开发语言·前端·javascript·react.js
阿丽塔~1 小时前
面试题之react useMemo和uesCallback
前端·react.js·前端框架