React18原理: 再聊Fiber架构下的时间分片

时间分片

  • react的任务可以被打断,其实就是基于时间分片的
  • 人眼最高能识别的帧数不超过30帧,电影的帧数差不多是在24
  • 浏览器的帧率一般来说是60帧,也就是每秒60个画面, 平均一个画面大概是16.5毫秒左右
  • 浏览器正常的工作流程是运算渲染,运算,渲染运算渲染
  • 在浏览器里面一个运算,加上一个渲染就是一帧
  • 总的来讲,可以理解为下面这张图
  • 比如 frame 是一帧,一个 Frame 就是16毫秒左右
  • 黑色部分是浏览器的渲染,蓝色部分是js的运算
  • 在16毫秒以内(一帧), 浏览器会重新渲染画面,然后再加上JS的一轮事件循环的执行
  • 根据任务队列循环下去,一秒 60 帧,每一帧都是 js的执行 + 浏览器的渲染
  • 但是, js它是单线程的, 会阻塞浏览器渲染, 假如 js执行时间超长,占了 3 ~ 4帧
  • js执行的时候,浏览器是不能渲染的,那这个时候会有页面卡顿的感觉
    • 实际上这个时候是 js 在执行
    • 这个也是react它去递归渲染的时候的问题
    • 递归渲染,它就是属于长进程,相当于在 render 的时候 js 一直把渲染进程给卡住
  • 这个是哥很苦恼的问题,所以诞生了fiber架构, react希望能够把任务分片处理
  • 这个时候就提到了一个概念,就是 fiber reconciler 要做的事情
  • 它如何让我们把时间分片,然后让又让浏览器不卡顿的呢?
    • 其实特别的巧妙,谷歌浏览器底层提供的一个东西叫做 requestIdleCallback
    • 前面说到一帧(16ms左右) 是 渲染 + js的执行
    • 有时候浏览器比较空闲,有可能一帧不需要 16ms,可能需要6ms, 那剩下的10ms可以执行长任务
    • 当剩下的10ms用完,可以把浏览器的渲染权利再还给浏览器
    • 这个时候进入下一帧的浏览器的画面,继续渲染,渲染完之后又有剩余时间
    • 接着再执行这个长进程,简单来说,就是把长进程拆分成一个个很小的任务
    • 它利用浏览器每一帧的空闲时间去执行,这样就实现了任务的打断,而且还不阻塞浏览器的渲染
  • 也就是说,本来一个任务要执行1秒,但是实际上react的fiber架构可能让这个1秒执行的时间更长
  • 因为任务的拆分其实是增加了这个计算的开销的,但是,它却是在我们每一帧的空闲时间去执行的
  • 虽然执行的整体时间可能变长,但是让用户的感觉没有那么卡顿,所以它的体验是提升了的
  • 参考之前 React 16的时间片:https://blog.csdn.net/Tyro_java/article/details/135586572

关于 requestIdleCallback

  • 文档:https://developer.mozilla.org/zh-CN/docs/Web/API/Window/requestIdleCallback

  • window.requestIdleCallback() 方法插入一个函数,这个函数将在浏览器空闲时期被调用

  • 这使开发者能够在主事件循环上执行后台和低优先级工作,而不会影响延迟关键事件,如动画和输入响应

  • 函数一般会按先进先调用的顺序执行,然而,如果回调函数指定了执行超时时间timeout,则有可能为了在超时前执行函数而打乱执行顺序

  • requestIdleCallback(callback)

  • requestIdleCallback(callback, options)

    • callback
      • 一个在事件循环空闲时即将被调用的函数的引用。函数会接收到一个名为 IdleDeadline 的参数
      • 这个参数可以获取当前空闲时间以及回调是否在超时时间前已经执行的状态
    • options 可选
      • 包括可选的配置参数。具有如下属性
        • timeout
          • 如果指定了 timeout,并且有一个正值,而回调在 timeout 毫秒过后还没有被调用
          • 那么回调任务将放入事件循环中排队,即使这样做有可能对性能产生负面影响
  • 返回值是一个ID,可以把它传入 Window.cancelIdleCallback() 方法来结束回调

requestIdleCallback 和 requestAnimationFrame 的区别


1 )react fiber 引起的关注

  • 组件树转换为链表,可分段渲染
  • 渲染时可以暂停,去执行其他高优先任务,空闲时再继续渲染
  • 如何判断空闲?requestIdleCallback

2 ) 区别

  • requestAnimationFrame 每次渲染完都会执行,高优

  • requestIdleCallback 空闲时才会执行,低优

    let curWidth = 100
    const maxWidth = 400function addWidth() {curWidth = curWidth + 3box.style.width = `${curWidth} px`if (curWidth < maxWidth) {widndow.requestAnimationFrame(addWidth) // 时间不用自己控制 高优先级widndow.requestIdleCallback(addWidth) // 时间不用自己控制 繁忙时不会执行}
    }addWidth()
    
  • 对比

    console.info('start')
    window.requestIdleCallback(()=>{console.log('requestIdleCallback')
    })
    window.requestAnimationFrame(()=>{console.log('requestAnimationFrame')
    })
    setTimeout(()=>{console.log('setTimeout')
    })
    console.info('end')
    
  • 执行顺序

    • start
    • end
    • timeout 优先级更高
    • requestAnimationFrame 宏任务优先级较高
    • requestIdleCallback 宏任务优先级较低
  • 总结

    • 两者都是宏任务
    • 需要等待dom渲染完才会执行

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/464950.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

二分搜索法的探究与心得

引言 在计算机科学中&#xff0c;二分搜索&#xff08;Binary Search&#xff09;算法是一种在有序数组中查找特定元素的基本搜索技术。其优点在于高效的搜索速度&#xff0c;时间复杂度为 ( O(log n) )&#xff0c;这一点与时间复杂度为O(n) 的线性搜索法相比&#xff0c;效率…

Spring Cloud Hystrix 参数配置、简单使用、DashBoard

Spring Cloud Hystrix 文章目录 Spring Cloud Hystrix一、Hystrix 服务降级二、Hystrix使用示例三、OpenFeign Hystrix四、Hystrix参数HystrixCommand.Setter核心参数Command PropertiesFallback降级配置Circuit Breaker 熔断器配置Metrix 健康统计配置Request Context 相关参数…

python 基础知识点(蓝桥杯python科目个人复习计划35)

今日复习计划&#xff1a;阶段总结&#xff08;新年贺礼&#xff09; 1.python简介&#xff08;定义&#xff0c;优点&#xff0c;缺点&#xff0c;应用领域&#xff09; python&#xff1a;一种广泛使用的解释型&#xff0c;高级和通用的编程语言 python极简&#xff0c;生…

python执行js代码

1. Python执行JavaScript代码 假如在爬虫逆向分析时&#xff0c;发现某个js加密算法比较繁琐&#xff0c;用Python还原同样的算法比较费劲。此时&#xff0c;可以不必使用Python还原&#xff0c;而是利用Python去直接调用JavaScript中定义的功能。 想实现Python调用JavaScrip…

六招,搞定大气上档次的可视化界面!有图有真相。

以下是一些设计可视化图表更加美观大气的建议&#xff1a; 选择合适的颜色&#xff1a; 颜色可以帮助人们更好地理解和记忆数据。选择颜色时&#xff0c;应该考虑颜色的对比度、亮度和饱和度等因素&#xff0c;同时也要考虑颜色的文化含义和情感效果。 使用合适的字体&#x…

【动态规划】1301. 最大得分的路径数目

作者推荐 【动态规划】【前缀和】【C算法】LCP 57. 打地鼠 本文涉及知识点 动态规划汇总 LeetCoce1301. 最大得分的路径数目 给你一个正方形字符数组 board &#xff0c;你从数组最右下方的字符 ‘S’ 出发。 你的目标是到达数组最左上角的字符 ‘E’ &#xff0c;数组剩余…

嵌入式系统的前景:未来智能汽车

&#xff08;本文为简单介绍&#xff0c;个人的观点仅供参考&#xff09; 智能汽车时代已经来临!未来十年,我们的汽车将变得越来越智能化。各大汽车公司在研发自动驾驶技术,目标是实现真正的无人驾驶。要实现这一目标,嵌入式系统将发挥关键作用。 简单来说,嵌入式系统就是在汽…

C++引用(内含和指针的对比)

1.引用的概念 概念&#xff1a;引用不是新定义一个变量&#xff0c;而是给已存在变量取了一个别名&#xff0c;编译器不会为引用变量开辟内存空间&#xff0c;它和它引用的变量共用一块内存空间。 类型& 引用变量名(对象名) 引用实体&#xff1b;&#xff08;&这个符…

###C语言程序设计-----C语言学习(11)#数据的存储和基本数据类型

前言&#xff1a;感谢您的关注哦&#xff0c;我会持续更新编程相关知识&#xff0c;愿您在这里有所收获。如果有任何问题&#xff0c;欢迎沟通交流&#xff01;期待与您在学习编程的道路上共同进步。 一. 数据的存储 1.整型数据的存储 计算机处理的所有信息都以二进制形式表示…

Python:解析获取连续的重叠对pairwise

简介&#xff1a;pairwise函数&#xff0c;返回从输入迭代器获取的重叠对的迭代器&#xff0c;是Python 3.10 新特性&#xff0c;表示一个迭代器从对象中获取连续的重叠对&#xff0c;在某些场景中可以优化代码运行效率。pairwise 函数是一种用于处理列表中元素之间配对操作的通…

基于Python的信息加密解密网站设计与实现【源码+论文+演示视频+包运行成功】

博主介绍&#xff1a;✌csdn特邀作者、博客专家、java领域优质创作者、博客之星&#xff0c;擅长Java、微信小程序、Python、Android等技术&#xff0c;专注于Java、Python等技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; …

VsCode中常用的正则表达式操作

在vscode中可以使用正则表达式来进行搜索内容&#xff0c;极大的方便了我们对大量数据中需要查看的信息进行筛选&#xff0c;使用正则搜索时点击 .* 此文章会持续补充常用的正则操作 1.光标选中搜索到的内容 将搜索的内容进行全选&#xff0c;举例&#xff1a;在如下文件中我需…