通過三個月的埋頭苦幹,終於完成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', } },