自从react从15版更新到16版后,虽然使用上差别不会很大也提供了一定的兼容性,但是react的底层架构确有了很大的变化。React Fiber横空出世...
React15最大的问题就是Reconciler阶段产生产生虚拟DOM是通过深度优先递归的,并且中途不可间断。所以假如虚拟DOM很深的话,由于JS线程和浏览器GUI线程是互斥的,处理js的时间过长,会导致浏览器刷新的时候掉帧,造成卡顿。而React16则实现了异步的可中断的更新。
那么Fiber到底是个啥?其实Fiber怎么说都可以...Fiber可以理解为一种架构,Fiber也可以理解为一种数据结构,也可以是常说的最小的工作单元。
常说的Fiber树就是将Fiber当作一种架构来看待的,Fiber怎么连接成树呢?三个关键的属性
// 指向父级Fiber节点
this.return = null;
// 指向子Fiber节点
this.child = null;
// 指向右边第一个兄弟Fiber节点
this.sibling = null;
所以在react16里面,一个组件对应的就是一棵Fiber树。那更新的时候,Fiber这棵树有什么作用呢?react16里面又一个很有意思的技术解答了——“双缓存技术”。
双缓存简单来说就是,在React里面最多同时存在两棵Fiber树,都在内存中构建,构建完成后直接替换。在源码里面,当前屏幕上显示内容对应的Fiber树称为current fiber树,正在内存中构建的Fiber树称为workInProgress fiber树。两棵树之间通过alternate属性连接。
currentFiber.alternate === workInProgressFiber;
workInProgressFiber.alternate === currentFiber;
那么Fiber和React里面重要的一个概念JSX有什么区别和联系呢?下面是React官网对JSX的定义
const element = <h1>Hello, world!</h1>;
?简单来说,JSX就是html+js,由于和UI的本质形式很相似,所以这理解起来也很轻松。而通过JSX创建的组件就是React15里面的虚拟DOM,实质上虚拟DOM是由React.createElement这个函数创建的。其中就要用到babel转译器了。
Babel转译JSX的过程简要:
- Babel通过parse()函数将JSX解析成AST抽象语法树,一种树状的形式表现编程语言的语法结构。
- 依据解析的AST,再通过Babel的transform()函数生成React.createElement()代码
再来看React.createElement()创建返回的JSX数据结构
return ReactElement(
type,
key,
ref,
self,
source,
ReactCurrentOwner.current,
props,
);
}
所以,由此可以看见,一个组件的JSX和Fiber节点的数据结构不同。组件在mount时,根据JSX来创建对应的Fiber节点。
?
?
React的源码和底层原理博大精深,也是全球一些顶尖的前端工作者花了几年的事件慢慢积淀下来的,所以还有巨大的学习空间。仅仅是我本人在学习时的一些记录和思考,如有不对的地方,欢迎批评指正!!!共同进步!后续会更新更多关于React原理性的东西~~~
|