通过三个月的埋头苦干,终于完成Fiber版的anujs。
主要特性有:react
这里着重说一下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,如今没有实现,临时糊弄一下你们。webpack
let deadline = { didTimeout: false, timeRemaining() { return 2; }, }; function requestIdleCallback(fn) { fn(deadline); } Renderer.scheduleWork = function() { performWork(deadline); };
performWork的实现相似于早期的rAF动画,发现还有任务没完工,就继续递归执行自身。git
// 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就会将第一个参数丢进去。es6
与1.3x同样,它是对IE8友好的,它全部使用的es6新特性均可以被babel polyfill及使用es3ify优雅降级。目前已经有IE8专用的脚手架可用:https://gitee.com/menhal/React_IE8_boilerplate
剩下就是须要你们同心合力发掘兼容性很好的React路由库与UI库。web
npm i anujs
webpack.config中如何代替原来用React编写的项目npm
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', } },