React Fiber 1

前言

随着mvvm模式的流行,现在大多数的前端框架基本都是在react和vue中选择其一,react的核心就是尽量避免开发者去操作真实的dom,可以让开发者直接操作数据,然后react来完成真实dom的更新。
react可以做到这一点,就是基于虚拟dom的reconciliation,其实就是对比两颗虚拟dom树的差异,然后渲染到浏览器上面。
但是人总是要有追求,两年前左右react就发现了reconciliation的一个潜在问题,就是在对比两颗树的时候,花费的时间太长,可能导致浏览器假死,所以就启动了一个项目来重写reconciliation,那就是react fiber.

为什么?

这里不得不提浏览器的渲染机制,现在基本上公认的是60fps,也就是说浏览器会在每秒内渲染60次,也就是基本上16.7ms渲染一次。
(为什么是60fps呢,这里和硬件的刷新频率有关系,有兴趣的可以查下)
基本渲染流程如下
1,执行js
2,样式计算
3,计算布局,执行
4,pait,绘制各层
5,合成各层的绘制结果,呈现在浏览器上。

所以基本上就是在16.7ms内执行完这些操作,就是比较完美的啦,但是事情不可能这么完美,比如如果js代码执行时间特别长的话,一直在等你的js执行完之后,才会去渲染,页面就是一直空白。

例子:

var then = Date.now()
  var i = 0
  var el = document.getElementById('message')
  while (true) {
    var now = Date.now()
    if (now - then > 1000) {
      if (i++ >= 10) {
        break;
      }
      el.innerText += 'hello!\n'
      console.log(i)
      then = now
    }
  }
Kapture 2018-12-07 at 13.12.01.gif

可以看到当js一直在运行,占用浏览器的主进程的时候,一直到所有的js运行完之后,才会把结果渲染到浏览器上面。
如果我们改下代码,让js长时间占用浏览器主进程的时候,页面就会一直刷新不出来。
比如把上面的代码里边的10,改成1000的时候,然后就会一直白屏,等到浏览器全部刷新完毕,才会显示出来。


22.gif

综上来看,最好的方式就是在浏览器的每一帧内,刷新一次,尽量不要让js长时间占据浏览器主进程。

这里就是为什么react fiber为什么会出现的原因了,因为之前的reconciliation也就是现在所说的stack reconciliation 就像是在一个人在水底下游泳,如果不是你感觉受不了,绝对不会浮出水面换气一样,在react里就是如果不把所有的差异都找到,绝对不会结束reconciliation。
http://conf.reactjs.org/ 上,Lin Clark 通过漫画为我们介绍 Fiber

这个就是以前的reconciliation图:


image.png

当所有的事情都等待reconciliation结束的时候,可能有其他更高级别的功能需求进来,比如用户点击输入框,或者是点击按钮等操作,但是由于还在执行,就会就一直卡住,让用户认为页面在假死。

所以Lin Clark介绍的最好的办法,也是用的最多的办法,不管是在计算机系统还是哪里,那就是分片,我借了你的东西,我用一段时间,就得过来就还给你,等你用完了之后,我再过来借一次,好借好还,再借不难。

比如和下图一样


image.png

这基本就是react fiber的核心所在!

Fiber node

什么是fiber node呢,fiber node其实和原来的虚拟dom有点类似,也是用来表示dom元素的描述的,但是如果只是这样,那和原来的虚拟dom也没什么区别了,而且也无法实现上面的暂停,继续等功能了。
可以看下源码里边fiber node的定义

image.png

可以看到fiber node 也是一个普通的对象,不过它里边包含了很多以前的虚拟dom里边没有的属性,比如return, child, sibling。(fiber 也是通过增加了这几个属性,将原来的递归,改成了一个链表)
类似下图

image.png

fiber node 就是一个包含了react dom的许多信息的普通对象。

fiber tree 算法

具体流程和原来的差不多,其实也还是找出两次更新之间的差异,然后渲染到浏览器上面。

  1. 首次render函数执行完之后,react会保存一份react fiber树,然后会循环利用,不会重复建立,称为curret 树。
    2,当有setstate或者其他的时候,就会根据现在的current树重新生成一份包含变化的树。

这里最重要的就是在对比两颗树的过程中是异步的,随时可以中断,恢复,但是当更新的时候是同步的,也就是说 diff 过程中,是异步,commit是同步的。

diff 具体过程

这里就是根据信息,来遍历workpress树然后找不不同,这里不一样的一点是因为加了很多的指针,类似加了很多直达电梯,节省了很多时间,可以直接到达。

任何一项工作都会有下面几步, 首先获取该在哪里做,然后开始做,再接着就是花时间干完这项工作,最后退出,继续寻找下一步该在哪里工作。
对应关系就是
获取该在哪里做: performUnitOfWork
开始做: beginWork
完成工作: completeUnitOfWork
寻找下一步哪里做: completeWork
所有的函数都在(packages/react-reconciler/src/ReactFiberScheduler.js)

可以看下别人做的效果图


1_A3-yF-3Xf47nPamFpRm64w.gif

这里要注意的唯一一点就是,
image.png

代表是子节点,比如上面的b1就是a1的子节点


image.png

代表兄弟节点,比如b3和b2就是兄弟节点。可以看到上面的处理方式在兄弟节点和父子节点之间的处理方式是不同的,不过比较简单,可以去看下。
唯一要记住的一点就是这里的过程是异步的,随时可能会暂停,或者停止,或者需要恢复过来重新执行。

commit

这里就是同步的了,不过速度也会很快的,因为这里把哪些改变了的fiber node形成了一个链表,如果中间没有更新的话,会快速的跳到下面去。

类似于下图的链表


image.png

参考链接:
https://medium.com/react-in-depth/inside-fiber-in-depth-overview-of-the-new-reconciliation-algorithm-in-react-e1c04700ef6e

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,591评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,448评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,823评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,204评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,228评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,190评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,078评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,923评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,334评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,550评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,727评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,428评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,022评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,672评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,826评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,734评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,619评论 2 354

推荐阅读更多精彩内容

  • 上次写了react整体框架的理解,这次想写写看对于新版React的新的React Fiber的实现。 在React...
    离开North阅读 1,591评论 1 2
  • 参考文章:深度剖析:如何实现一个Virtual DOM 算法 作者:戴嘉华React中一个没人能解释清楚的问题——...
    waka阅读 5,965评论 0 21
  • react刚刚推出的时候,讲react优势搜索结果是几十页。 现在,react已经慢慢退火,该用用react技术栈...
    zhoulujun阅读 5,198评论 0 11
  • eact框架的出现,意味着前端进入了一个新的时代。 作为后端,开始做前端的相关项目以来已经有段时间,刚开始使用Re...
    离开North阅读 2,828评论 0 4
  • 今天是一个很开心的日子,天气晴朗暖和,3,24号,兴安小学组织孩子去青云山植树活动,我也报上名和孩子一起去, 我们...
    刘皓元阅读 233评论 0 0