2020年11月05日(Concurrent Mode)


Concurrent Mode

官方文档https://react.docschina.org/docs/concurrent-mode-intro.html

可中断的rendering

在通常状况下,React 在 render 的时候是没有办法被打断的,(在react15中使用的是递归,在react16中用到了fiber(纤程)),JS可以操作DOM,GUI渲染线程与JS线程是互斥的。所以JS脚本执行浏览器布局、绘制不能同时执行

当用户在输入框输入内容时,会产生卡顿,因为每一次重新渲染都将阻塞主线程(关于进程,线程,协程不了解的话可以看这篇文章https://www.cnblogs.com/williamjie/p/11195069.html
浏览器就没有办法实时的响应用户在输入框输入的东西,一般会使用防抖和节流,但是治标不治本

但是如果区分优先级,比如当我再输入框输入的时候,React 可以暂停 render 让浏览器优先对用户的输入进行更新,然后 React 会在内存中渲染最新的页面,等到第一次 render 完成后再直接将最新的页面更新出来,保证用户能看到最新的页面。

主流浏览器刷新频率为60Hz,即每(1000ms / 60Hz)16.6ms浏览器刷新一次。

在每16.6ms时间内,需要完成如下工作:

JS脚本执行 -----  样式布局 ----- 样式绘制

开启Concurrent Mode后在浏览器每一帧的时间中,预留5ms给JS线程,React利用这部分时间更新组件。当预留时间执行完后,react将线程控制权交还给浏览器使其有时间渲染UI,下一帧的时候在继续中断的任务

当网络延迟时候可以先在当前页面停留了一小段时间,这一小段时间被用来请求数据,当这一小段时间足够短时,用户是无感知的。如果请求时间超过一个范围,再显示loading的效果。react17中也提供了配套的方法useDeferredValue,还有useTransition

Concurrent Mode将同步的更新变为可中断的异步更新,通过启用 Fiber reconciler 实现了可打断的渲染,在react15是没有调度器(Scheduler)的只有协调器Reconciler(Stack Reconciler)和渲染器Renderer,不能打断这也是为什么有了fiber的原因

Fiber架构配合Scheduler实现了Concurrent Mode的底层 —— “异步可中断的更新”。


Author: wxy
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint policy. If reproduced, please indicate source wxy !
  TOC