经过三个月的埋头苦干,终于完成Fiber版的anujs。

主要特性有:

  • 测试全部改成jest, 迁移官方测试用例。有许多迷你React吹得怎么天花乱坠,但是生命周期钩子的执行顺序无法与官方保持一致,那么就很难共享React庞大的资源。像深度使用React内部 机制的ReactRouter与antd就无法使用。

    支持新钩子,包括getDerivedStateFromProps,getDerivedStateFromCatch, getSnapshotBeforeUpdate,componentDidCatch。新钩子的诞生与已有的三个componentWillXXX 钩子的废弃是同步进行的,你在组件里定义了新钩子,那旧钩子就不会被调起。

    支持批量更新API,ReactDOM.unstable_batchedUpdates, 这原本在React15的事件回调执行setState就存在的一种优化技术。现在官方将它大众化。

    将createClass移出核心库,已经2018年了,应该接受es6的洗礼。

    重构错误边界,只差一个用例就跑通官方测试了。

    重构受控组件,全部用例跑通。

    更新划分目录,源码放在packages下,分成core, fiber与render。core对应react.js,包括一些公用方法与内置组件(Fragment组件, Portal组件, PureComponent组件, forwardRef高阶组件)。fiber就是React16的异步架构。render包含了不同的渲染器,dom, noop(测试用), server。职责分明,有利于后继的调优。

    支持antd 99%组件,目前只发现transfer有点问题。

这里着重说一下fiber版块下的设计。

unbatch内置了一个Unbatch组件,它用来模拟React内部的unbatchedUpdates。

scheduleWork里面有一个updateComponet方法,setState的真正实现,用于驱动某一棵树的更新。ReactDOM.render(vdom, container, cb)也会调用它进行更新,不过在我们container与vdom中,我们放进了一个Unbatch组件。调用ReactDOM.render相当于调用了Unbatch组件的setState, setState有第二个可选参数cb, 也就相当于ReactDOM.render的第三个可选cb。updateComponet最里面是scheduleWork方法,它按理是使用大名鼎鼎的requestIdleCallback,现在没有实现,临时糊弄一下大家。

let deadline = {
didTimeout: false,
timeRemaining() {
return 2;
},
}; function requestIdleCallback(fn) {
fn(deadline);
}
Renderer.scheduleWork = function() {
performWork(deadline);
};

performWork的实现类似于早期的rAF动画,发现还有任务没完工,就继续递归执行自身。

// rAF动画的示范代码
var start = null;
var element = document.getElementById('SomeElementYouWantToAnimate');
element.style.position = 'absolute'; function step(timestamp) {
if (!start) start = timestamp;
var progress = timestamp - start;
element.style.left = Math.min(progress / 10, 200) + 'px';
if (progress < 2000) { //递归执行自身
requestAnimationFrame(step);
}
} requestAnimationFrame(step)
performWork的代码也是如此
function performWork(deadline) {
//执行当前的所有任务,更新虚拟DOM与真实DOM
workLoop(deadline);
//忽略其他往macrotasks中添加任务的代码。。。
//忽略其他往macrotasks中添加任务的代码。。。
//忽略其他往macrotasks中添加任务的代码。。。
if (macrotasks.length) {
requestIdleCallback(performWork);
}
}

ReactFiber相当于伪造了一个浏览器,因此有自己调度器,事件列队。于是你可以看到macrotasks,microtasks,batchedtasks, boundaries, effects等列队。

macrotasks,宏列队,主进程,一个页面只有一个, ReactDOM.render就会将第一个参数丢进去。

2. microtasks,微列队,子进程,每棵虚拟DOM树都有一个,放在根节点中。当组件执行setState后,它会找到根节点的microtasks,然后放进去。然后在下次唤起performWork时,会从所有根节点中收集它们。

3. batchedtasks,批量处理的任务,它们不能被合并。microtasks中的任务,都是由setState产生的,我们知道对某个组件进行多次setState,React在一次生命周期中会执行一次更新。batchedtasks则不一样,它们是延后到下次生命周期,因此不能在这次生命周期中就被执行了。

4. boundaries,放着边界组件,边界组件会有很高的优先级,确保它们下次在performWork中,加入macrotasks的最前面。

5. effects,它是commit阶段执行的macrotasks 列队。

workLoop有两个DFS遍历,reconcileDFS与commitDFS。reconcileDFS负责更新虚拟DOM,commitDFS负责更新真实DOM。为什么强调使用DFS,因为这东西对我们存取context, container非常方便。

注意:

anujs改动比较大,导致原先的DevTool不能用,这也是后继的工作重点了。

虽然这次改动这么大,它的体积还是相当迷你的。

与1.3x一样,它是对IE8友好的,它所有使用的es6新特性都可以被babel polyfill及使用es3ify优雅降级。目前已经有IE8专用的脚手架可用:https://gitee.com/menhal/React_IE8_boilerplate

剩下就是需要大家同心协力发掘兼容性很好的React路由库与UI库。

npm i anujs

webpack.config中如何代替原来用React编写的项目

resolve: {
alias: {
'react': 'anujs',
'react-dom': 'anujs',
// 若要兼容 IE 请使用以下配置
// 'react': 'anujs/dist/ReactIE',
// 'react-dom': 'anujs/dist/ReactIE', // 如果引用了 prop-types 或 create-react-class
// 需要添加如下别名
'prop-types': 'anujs/lib/ReactPropTypes',
'create-react-class': 'anujs/lib/createClass'
//如果你在移动端用到了onTouchTap事件
'react-tap-event-plugin': 'anujs/lib/injectTapEventPlugin',
}
},

anujs1.4.0发布的更多相关文章

  1. 高性能迷你React框架anujs1.1.0发布

    本版本对setState与forceUpdate内部依赖的setStateImpl进行了重构,性能稳定在60pfs之上.并且将组件实例的所有内部方法与属性都改成以___开头. https://gith ...

  2. Visual Studio Code 1.0发布,支持中文在内9种语言

    Visual Studio Code 1.0发布,支持中文在内的9种语言:Simplified Chinese, Traditional Chinese, French, German, Italia ...

  3. Apache Flume 1.7.0 发布,日志服务器

    Apache Flume 1.7.0 发布了,Flume 是一个分布式.可靠和高可用的服务,用于收集.聚合以及移动大量日志数据,使用一个简单灵活的架构,就流数据模型.这是一个可靠.容错的服务. 本次更 ...

  4. Percona Server 5.6.33-79.0 发布

    Percona Server 5.6.33-79.0 发布了,该版本基于 MySQL 5.6.33,包含了所有的 bug 修复,是Percona Server 5.6 系列中的正式版本.该版本主要是修 ...

  5. Rubinius 2.0 发布,Ruby 虚拟机

    Rubinius 2.0 发布了,官方发行说明请看这里. Rubinius是一个运行Ruby程序的虚拟机,其带有Ruby的核心库. Rubinius的设计决定了其调试功能的强大,使得在运行时常规的Ru ...

  6. Restful.Data v2.0发布,谢谢你们的支持和鼓励

    v1.0发布后,承蒙各位博友们的热心关注,也给我不少意见和建议,在此我真诚的感谢 @冰麟轻武 等朋友,你们的支持和鼓励,是这个开源项目最大的推动力. v2.0在除了细枝末节外,在功能上主要做了一下更新 ...

  7. 网页动物园2.0发布,经过几个月的努力,采用JAVA编写!

    网页动物园2.0发布,经过几个月的努力,采用JAVA编写! 网页动物园2.0 正式发布!游戏发布 游戏名称: 网页动物园插件 游戏来源: 原创插件 适用版本: Discuz! X1.5 - X3.5 ...

  8. Redisson-Parent 2.5.0 和 3.0.0 发布

    Redisson-Parent 2.5.0 和 3.0.0 发布了,Redisson 是基于 Redis 服务之上构建的分布式.可伸缩的 Java 数据结构,高级的 Redis 客户端. Rediss ...

  9. Rsync 3.1.0 发布,文件同步工具

    文件同步工具Rsync 3.1.0发布.2013-09-29 上一个版本还是2011-09-23的3.0.9 过了2年多.Rsync基本是Linux上文件同步的标准了,也可以和inotify配合做实时 ...

随机推荐

  1. Vector Math for 3D Computer Graphics (Bradley Kjell 著)

    https://chortle.ccsu.edu/VectorLessons/index.html Chapter0 Points and Lines (已看) Chapter1 Vectors, P ...

  2. [ZZ] Valse 2017 | 生成对抗网络(GAN)研究年度进展评述

    Valse 2017 | 生成对抗网络(GAN)研究年度进展评述 https://www.leiphone.com/news/201704/fcG0rTSZWqgI31eY.html?viewType ...

  3. C# .NET MODEL 复制,实体类复制

    -- /// <summary> /// 将T1 实体的参数复制给 T2 ,不能处理多层次 /// </summary> /// <typeparam name=&quo ...

  4. CSS 不规则图形绘制

    基础技能1 - 神奇的border 我们先来画一个长方形: .Rectangle { height: 100px; width: 200px; background: darkgray; border ...

  5. Read The Docs搭建

    #!/bin/sh ########################### base ###################### yum -y update yum -y install yum-u ...

  6. Group(), Groups(),& Groupdict() 用法

    group() 返回一个或多个匹配的字串.如果只有一个参数,结果只有单个字符串:如果有多个参数,结果是一个元组,元组里每一项对应一个参数.没有参数,group1默认是0(整个匹配串被返回).如果gro ...

  7. 【Jquery Mobile教程】【问题】- 在页面切换时会闪烁

    用jQuery mobile开发移动应用和web应用的时候,页面切换会闪烁. 感觉,造成这样的原因大概是jQuery mobile在移动浏览器下的性能不佳造成的.jQuery mobile页面切换可以 ...

  8. 2018秋寒假作业6—PTA编程总结3

    1.实验代码 7-1 抓老鼠啊~亏了还是赚了? (20 分) 某地老鼠成灾,现悬赏抓老鼠,每抓到一只奖励10元,于是开始跟老鼠斗智斗勇:每天在墙角可选择以下三个操作:放置一个带有一块奶酪的捕鼠夹(T) ...

  9. ZooKeeper是按照CP原则构建的,不适合做Service服务发现

    一.cap 分布式领域中存在CAP理论,且该理论已被证明:任何分布式系统只可同时满足两点,无法三者兼顾. ①C:Consistency,一致性,数据一致更新,所有数据变动都是同步的. ②A:Avail ...

  10. LeetCode【112. 路径总和】

    思路就是从根节点开始向下选节点,依次与sum比较大小,若小,则向下选左右节点其中一个,若大,则接下来判断是否是叶子节点,若是,则返回false 若不是,则上一步选另一节点,再将上述重新执行. 对于叶子 ...