React18原理: 时间分片技术选择

这篇具有很好参考价值的文章主要介绍了React18原理: 时间分片技术选择。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

渲染1w个节点的不同方式


1 )案例1:一次渲染1w个节点

<div id='root'><div>

<script type="text/javascript">
	function randomHexColor() {
		return "#" + ("0000"+ (Math.random() * 0x1000000 << 0).toString(16)).substr(-6);
	}

	setTimeout(function() {
		var k = 0;
		var root = document.getElementById("root");
		for(var i = 0; i < 10000; i++) {
			k += new Date - 0 ;
			var el = document.createElement("div");
			el.innerHTML = k;
			root.appendChild(el);
			el.style.cssText = `background: ${randomHexColor()};height: 40px`;
		}
	},1000);
</script>

1 次完成 1w 个节点的渲染

React18原理: 时间分片技术选择,React | React Native,javascript,前端,前端框架

可以看到,圈中的部分,明显被阻塞,这一块绝对会导致用户体验很差

2 )案例2: 1w 个节点分100次执行,每次执行100个

<div id='root'><div>

<script type="text/javascript">
	var root = document.getElementById("root");

	function randomHexColor() {
		return "#" + ("0000"+ (Math.random() * 0x1000000 << 0).toString(16)).substr(-6);
	}

	function loop(n) {
		var k = 0;
		console.log(n);
		for(var i = 0; i < 100; i++) {
			k += new Date - 0 ;
			var el = document.createElement("div");
			el.innerHTML = k;
			root.appendChild(el);
			el.style.cssText = `background: ${randomHexColor()};height: 40px`;
		}
		if (n) {
			// 内部再调用 n-1次 loop,总计调用 n 次 loop
			setTimeout(function() {
				loop(n - 1);
			}, 40)
		}
	}

	// 1s 执行一次
	setTimeout(function() {
		loop(100)
	}, 1000);
</script>
  • 这里,40ms 执行一次,100次,共4s执行完成
React18原理: 时间分片技术选择,React | React Native,javascript,前端,前端框架
  • 可以看到,没有明显的阻塞

为什么会有如此区别

  • 究其原因是因为浏览器是单线程,它将GUI描绘,时间器处理,事件处理,JS执行远程资源加载统统放在一起,当做某件事,只有将它做完才能做下一件事
  • 如果有足够的时间,浏览器是会对我们的代码进行编译优化(JIT) 及进行热代码优化,一些DOM操作,内部也会对reflow进行处理
  • reflow是一个性能黑洞,很可能让页面的大多数元素进行重新布局
  • 所以,浏览器歇一会儿跑一会儿,比一直跑性能更好

时间分片技术方案选择


1 )注意兼容问题

  • 注意,在 request18 版本并没有使用 requestIdleCalback, 仍旧因为兼容问题

2 ) 方案选择

  • 在浏览器环境中,常见的macro task有setTimeout、MessageChannel、postMessage
  • 而常见的 micro task 有 MutationObsever, Promise.then

2.1 微任务问题

  • 为什么不使用微任务呢?
  • 宏任务是在下一轮事件循环中执行,微任务是在当前时间循环中执行
  • 微任务将在页面更新前全部执行完,也就是是要在当前帧执行完的,所以达不到「将主线程还给浏览器」的目的
  • 使用微任务就会造成一个问题,在极端情况下,一直卡在当前帧,因为微任务是在当前帧执行完的(本轮事件循环内)
  • 所以在 setTimeout, MessageChannel, postMessage 三选一
  • 为什么不使用setTimeout(fn,0)呢?
    function timer() {
      console.ltme('计时器')
      setTimeout(() => {
        console.timeEnd('计时器')
        timer()
      }, 0)
    }
    
    timer()
    
    • 递归的setTimeout()调用会使调用间隔变为4ms,导致浪费了4ms
    • 这是一个递归的定时器,在递归的时候,看下它的间隔时间
    • 在定时器递归大约4次以后,它的递归时间就变成了4ms~ 5ms 变得不准确
    • 明明我们指定的是 0ms, 这里差距有些大了,所以这个api有些问题,误差太大

2.2 宏任务问题

  • 为什么不使用 rAF() 呢?

    • 如果上次任务调度不是rAF()触发的,将导致在当前帧更新前进行两次任务调度
    • 页面更新的时间不确定,如果浏览器间隔了10ms才更新页面,那么这10ms就浪费了
  • React Scheduler使用MessageChannel的原因为:生成宏任务,实现:文章来源地址https://www.toymoban.com/news/detail-832006.html

    • 将主线程还给浏览器,以便浏览器更新页面
    • 浏览器更新页面后继续执行未完成的任务
      const { port1, port2 } = new MessageChannel();
      
      port1.onmessage = function (event){
        console.log('收到来自port2的消息:', event.data);//收到来自port2的消息: pong
      };
      
      port2.onmessage = function (event) {
        console.log('收到来自port1的消息:', event.data);//收到来自port1的消息: ping
        port2.postMessage('pong');
      };
      port1.postMessage('ping');
      

到了这里,关于React18原理: 时间分片技术选择的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 跨端技术栈综合考察:深入剖析 UniApp、Flutter、Taro 和 React Native 的优势与限制

    📈「作者简介」:前端开发工程师 | 蓝桥云课签约作者 | 技术日更博主 | 已过四六级 📚「个人主页」:阿珊和她的猫 🕐「简历必备」前后端实战项目(推荐:⭐️⭐️⭐️⭐️⭐️) Vue.js 和 Egg.js 开发企业级健康管理项目 带你从入门到实战全面掌握 uni-app UniApp 是一种 基

    2024年02月16日
    浏览(37)
  • 【react】react18的学习(十一)– 底层原理(一)之 diff 算法

    diff算法、fiber链表 步骤:(追求多复用,快渲染) 首次渲染,缓存虚拟dom或fiber链表(17及以后); 组件更新,将新生成的虚拟dom与已有的真实dom的fiber链表对比; 遵循同级对比、深度对比原则,先依次找节点对比; 对比过程中,第一轮对比:按链表顺序对比,节点key值相

    2024年02月17日
    浏览(38)
  • React18原理: React核心对象之ReactElement对象和Fiber对象

    React中的核心对象 在React应用中,有很多特定的对象或数据结构.了解这些内部的设计,可以更容易理解react运行原理 列举从react启动到渲染过程出现频率较高,影响范围较大的对象,它们贯穿整个react运行时 如 ReactElement 对象 如 Fiber 对象 其他过程的重要对象 如事件对象(位

    2024年02月19日
    浏览(32)
  • 【react】react18的学习(十二)– 底层原理(二)之 迭代器 iterator

    迭代器iterator 是一种 ES6 规范,具有这种机制的数据结构才可以使用 for of 循环:返回每一项的值; 原型链具有 Symbol.iterator 属性的数据结构都具备;如数组、部分类数组、字符串等; 普通对象就不能用; for-of循环原理:循环获取属性值; 执行可迭代原型链上的 Symbol.iterat

    2024年02月16日
    浏览(52)
  • React18原理: 生命周期中特别注意事项

    概述 生命周期就是一个组件从诞生到销毁的全过程(包含错误捕获,这里暂且不聊这个) react 在组件的生命周期中注册了一系列的钩子函数 支持开发者在其中嵌入代码,并在适当的时机运行 生命周期本质上就是组件中的钩子函数,主要有三个主要的钩子 挂载 更新 卸载 首次挂

    2024年02月20日
    浏览(32)
  • react native 0.73 配置 react-native-fs

    npm yarn android/settings.gradle android/app/build.gradle androidappsrcmainjavacomreactnative_demoMainApplication.kt 把原代码 改为

    2024年04月08日
    浏览(43)
  • 探索React Native的世界:gorhom/react-native-animated-tabbar

    项目地址:https://gitcode.com/gorhom/react-native-animated-tabbar 在移动应用开发领域,React Native以其高效、跨平台的能力受到了广泛的欢迎。今天,我们要向您推荐一个极具创意且实用的React Native组件库——gorhom/react-native-animated-tabbar。它是一个精美设计的动画TabBar,为您的应用提供生

    2024年04月17日
    浏览(82)
  • React与React Native的异同

    开发React一段时间了,一直没有搞清楚React和React Native的差异。今天特意去了解下,发现差异还真不小! 相同点: 1.都是Facebook公司推出的框架。 2.都是基于JSX语言开发的。 差异点: 1、作用的平台不同. 2、工作原理不同. 3、渲染周期不同. 4、组件构成形式不同. 5、宿主平台的

    2024年02月06日
    浏览(43)
  • 维护积极的react native,为什么会有人造谣react native不维护了,停止维护。

            其实近几年我一直关注react -native,他一直更新频繁,0.60大重构,升级了js执行引擎Hermes,当前已经0.70.4版本了。性能越来越提高,但是总感觉到有人在刷百度,只要输入react-native后面就自动提示热搜“react-native 停止维护”,这误导很多人以为真的不维

    2024年02月11日
    浏览(43)
  • 工欲善其事,必先利其器之—react-native-debugger调试react native应用

    调试react应用通常利用chrome的inspector的功能和两个最常用的扩展 1、React Developer Tools (主要用于debug组件结构) 2、Redux DevTools (主要用于debug redux store的数据) 对于react native应用,我们一般就使用react-native-debugger了,它是一个独立的应用,需要单独安装,在mac下可以用如下命令

    2024年02月16日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包