标签:contain get err 映射 star red state 卡顿 prot
? 视频课程的目的是为了快速掌握react源码运行的过程和react中的scheduler、reconciler、renderer、fiber等,并且详细debug源码和分析,过程更清晰。
? 视频课程:进入课程
? demos:demo
? 在前面的课程中我们已经学习了react的整体工作流程,对各个流程做的事情也有了大致的认识,现在让我们从react的入口开始学习各个部分的源码吧。
? 首先,react有3种模式进入主体函数的入口,我们可以从 react官方文档 使用 Concurrent 模式(实验性)中对比三种模式
ReactDOM.render(<App />, rootNode)
。这是当前 React app 使用的方式。当前没有计划删除本模式,但是这个模式可能不支持这些新功能。ReactDOM.createBlockingRoot(rootNode).render(<App />)
。目前正在实验中。作为迁移到 concurrent 模式的第一个步骤。ReactDOM.createRoot(rootNode).render(<App />)
。目前在实验中,未来稳定之后,打算作为 React 的默认开发模式。这个模式开启了所有的新功能。特性对比:
*:legacy 模式在合成事件中有自动批处理的功能,但仅限于一个浏览器任务。非 React 事件想使用这个功能必须使用 unstable_batchedUpdates
。在 blocking 模式和 concurrent 模式下,所有的 setState
在默认情况下都是批处理的。
**:会在开发中发出警告。
? legacy模式是我们常用的,它构建dom的过程是同步的,所以在render的reconciler中,如果diff的过程特别耗时,那么导致的结果就是js一直阻塞高优先级的任务(例如用户的点击事件),表现为页面的卡顿,无法响应。
? concurrent Mode是react未来的模式,它用时间片调度实现了异步可中断的任务,根据设备性能的不同,时间片的长度也不一样,在每个时间片中,如果任务到了过期时间,就会主动让出线程给高优先级的任务。这部分将在第11节 scheduler&lane模型 这章会具体讲解react是如何实现异步可中断的任务,以及任务的优先级和高优先级是如果插队的。
主要流程:
主要函数执行过程:
看断点调试视频,函数调用细节更清楚:
用demo_0来看看执行过程:
legacy模式:
//最上层的节点是整个项目的根节点fiberRootNode
ReactDOM.render(<App />, document.getElementById("root"));//rootFiber
ReactDOM.render(<App />, document.getElementById("root"));//rootFiber
?
concurrent模式:
?
function legacyRenderSubtreeIntoContainer(parentComponent, children, container, forceHydrate, callback) {
//...
var root = container._reactRootContainer;
var fiberRoot;
if (!root) {
// mount时
root = container._reactRootContainer = legacyCreateRootFromDOMContainer(container, forceHydrate);//创建root节点
fiberRoot = root._internalRoot;
if (typeof callback === ‘function‘) {//处理回调
var originalCallback = callback;
callback = function () {
var instance = getPublicRootInstance(fiberRoot);
originalCallback.call(instance);
};
}
unbatchedUpdates(function () {
updateContainer(children, fiberRoot, parentComponent, callback);//创建update入口
});
} else {
// update时
fiberRoot = root._internalRoot;
if (typeof callback === ‘function‘) {//处理回调
var _originalCallback = callback;
callback = function () {
var instance = getPublicRootInstance(fiberRoot);
_originalCallback.call(instance);
};
}
updateContainer(children, fiberRoot, parentComponent, callback);
}
}
function createFiberRoot(containerInfo, tag, hydrate, hydrationCallbacks) {
var root = new FiberRootNode(containerInfo, tag, hydrate);//创建fiberRootNode
const uninitializedFiber = createHostRootFiber(tag);//创建rootFiber
//rootFiber和fiberRootNode连接
root.current = uninitializedFiber;
uninitializedFiber.stateNode = root;
//创建updateQueue
initializeUpdateQueue(uninitializedFiber);
return root;
}
//对于HostRoot或者ClassComponent会使用initializeUpdateQueue创建updateQueue,然后将updateQueue挂载到fiber节点上
export function initializeUpdateQueue<State>(fiber: Fiber): void {
const queue: UpdateQueue<State> = {
baseState: fiber.memoizedState,//初始state,后面会基于这个state,根据Update计算新的state
firstBaseUpdate: null,//Update形成的链表的头
lastBaseUpdate: null,//Update形成的链表的尾
//新产生的update会以单向环状链表保存在shared.pending上,计算state的时候会剪开这个环状链表,并且连接在 //lastBaseUpdate后
shared: {
pending: null,
},
effects: null,
};
fiber.updateQueue = queue;
}
function updateContainer(element, container, parentComponent, callback) {
var lane = requestUpdateLane(current$1);//获取当前可用lane 在12章讲解
var update = createUpdate(eventTime, lane); //创建update
update.payload = {
element: element//jsx
};
enqueueUpdate(current$1, update);//update入队
scheduleUpdateOnFiber(current$1, lane, eventTime);//调度update
return lane;
}
function scheduleUpdateOnFiber(fiber, lane, eventTime) {
if (lane === SyncLane) {//同步lane 对应legacy模式
//...
performSyncWorkOnRoot(root);//render阶段的起点 render在地6章讲解
} else {//concurrent模式
//...
ensureRootIsScheduled(root, eventTime);//确保root被调度
}
}
function ensureRootIsScheduled(root, currentTime) {
//...
var nextLanes = getNextLanes(root, root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes); //计算nextLanes
//...
//将lane的优先级转换成schduler的优先级
var schedulerPriorityLevel = lanePriorityToSchedulerPriority(newCallbackPriority);
//以schedulerPriorityLevel的优先级执行performConcurrentWorkOnRoot 也就是concurrent模式的起点
newCallbackNode = scheduleCallback(schedulerPriorityLevel,performConcurrentWorkOnRoot.bind(null, root));
}
4.从legacy或concurrent开始(从入口开始,然后让我们奔向未来)
标签:contain get err 映射 star red state 卡顿 prot
原文地址:https://www.cnblogs.com/xiaochen1024/p/14408182.html