發佈高性能迷你React框架anu

anu, 讀做[安努],原意爲蘇美爾的主神。javascript

anu是我繼avalon以後又一個新框架(github倉庫爲https://github.com/RubyLouvre/anu, 歡迎加星與試用)css

此框架的創立之意有三:html

  1. 提高性能, 雖然React的性能相對於傳統的MVVM框架是很厲害了,但近幾年冒出來的diff算法比官方版更優秀,官方版積重難返,很難短時期吸取這些成果。anu則小船好調頭,第一時間收納其中。性能是王道。天下武功,惟快不破。java

  2. 壓縮體積。 React+React-dom加起來有三萬多行,這麼大的體量任何code splitting與按需加載技術都無能爲力,所以咱們須要迷你版的體積。react

  3. 卓越的瀏覽器兼容性。 React在生產環境中沒有用到什麼新式偏門的API,所以原本就能夠兼容到IE8之下。兼容性越好,咱們的後顧之憂越少。webpack

這三個特色都是爲擴展React的通用性而努力。git

在開發過程當中,先是參考react-lite搞了一個版本,遇到問題後又根據preact搞了一版,第二版成功後命名爲qreact,已經在公司的項目中用。es6

第二版的特色是preact改+preact.compat改+自創事件系統+diff機制改。反正通過此次研發後,咱們已經掌握了React的許多機制,可是尚未吃透preact的diff。github

不過騰出時間來後,開始第三版,就是如今開源出來的anu,它大部分機制是自創的,diff機制採起react-lite。性能比第二代qreact強許多。web

如下是成品anu的賣點:

  1. 支持React的無狀態組件,純組件,高階組件,受控組件與非受控組件
  2. 命名空間就是React,此外還暴露了另外一個別名ReactDOM在window上,免得在webpack上使用別名了。
  3. 體積很是小(1700行相對於react+react-dom的3萬行)
  4. 性能是官方React的兩倍以上 測試頁面結果統計
  5. 生命週期函數的參數與官方保持一致
  6. 直接與react-redux, react-router-dom, react-router-redux混用
  7. 支持後端渲染
  8. 支持官方的chrome DevTools

若是你想將它應用於IE8或之下,須要如下補丁

低版本瀏覽器可能須要如下 語言補丁

  1. Array.isArray
  2. Object.assign
  3. JSON.stringify
  4. console-polyfill
  5. es6-Map

或者直接使用polyfill.js https://github.com/RubyLouvre/anu/tree/master/dist/polyfill.js

詳細用法與示例見官網 ,如下我會寫文章展開介紹它的用法。下面是一些小例子:

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <script type='text/javascript' src="./dist/React.js"></script>
    <script src="https://cdn.bootcss.com/babel-standalone/6.24.0/babel.js"></script>

    <script  type="text/babel" >
       class A extends React.PureComponent {
            constructor(props) {
                super(props)
                this.state = {
                    aaa: {
                        a: 7
                    }
                }
            }
          
            click() {
                this.setState(function(state){
                   state.aaa.a = 8
                })
            }
            render() {
                return  <div onClick={this.click.bind(this) }>{this.state.aaa.a}</div>
            }
        }
        window.onload = function () {
            ReactDOM.render(<A />, document.getElementById('example'))
        }
    </script>
</head>

<body>
    <div>這個怎麼點擊也不會變</div>
    <blockquote id='example'></blockquote>


</body>

</html>

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <script type='text/javascript' src="./dist/React.js"></script> 
    <script src="https://cdn.bootcss.com/babel-standalone/6.24.0/babel.js"></script>
    <script  type="text/babel" >
  
    class Select extends React.Component{
        constructor(props){
           super(props)

           this.state = {
               value: props.value
           }
           this.onUpdate = props.onUpdate
           this.onChange = this.onChange.bind(this)
        }
        componentWillReceiveProps(props){
           this.state = { //更新本身
               value: props.value
           }
        }
        onChange(e){//讓父組件更新本身
            this.onUpdate(e.target.value)
        }
        render(){
            return <select value={this.state.value} onChange={this.onChange}>
                <option>北京</option>
                <option>南京</option>
                <option>東京</option>
                </select>
        }
    }
    class App extends React.Component{
       constructor(props){
           super(props)
           this.state = {
               value: '南京'
           }
        }
        onUpdate(value){ //讓子組件調用這個父組件的方法
             this.setState({
                value: value
            })
        }
        onChange(e){
           this.onUpdate(e.target.value)
 
        }
        render(){
          return  <div><Select onUpdate={this.onUpdate.bind(this)} value={this.state.value} /><input value={this.state.value} onChange={this.onChange.bind(this)} /></div>
        }

    }

window.onload = function () {
   
 ReactDOM.render(<App />,
   document.getElementById('example'))

}
    </script>
</head>

<body>
  
    <div>測試</div>
    <blockquote id='example'></blockquote>

</body>

</html>

與Redux使用的例子

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <script type='text/javascript' src="./dist/React.js"></script>
    <script src="https://cdn.bootcss.com/redux/3.6.0/redux.js"></script>

    <script src="./test/babel.js"></script>
    <script type='text/babel'>
        var addTodoActions = function (text) {
            return {
                type: 'add_todo',
                text: text
            };
        }
        var todoReducer = function (state, action) {

            if (typeof state === 'undefined') {
                return [];
            }

            switch (action.type) {
                case 'add_todo':
                    return state.slice(0).concat({
                        text: action.text,
                        completed: false
                    });
                    break;
                default:
                    return state;
            }
        };
        var store = Redux.createStore(todoReducer);
        class App extends React.Component {
            constructor(props){
                super(props)
                this.state = {
                    items: store.getState()
                }
                this.onChange = this.onChange.bind(this)
                this.handleKeyUp = this.handleKeyUp.bind(this)
                this.handleAdd = this.handleAdd.bind(this)
            }
            componentDidMount(){
                var unsubscribe = store.subscribe(this.onChange);
            }
            onChange(){
                this.setState({
                    items: store.getState()
                });
            }
            handleKeyUp(e){
                if(e.which === 13){
                   this.handleAdd()
                }
            }
            handleAdd(){
                var input = this.refs.todo
                var value = input.value.trim();

                if(value)
                    store.dispatch(addTodoActions(value));

                input.value = '';
            }
            render(){
                return (
                    <div>
                        <input ref="todo" type="text" placeholder="輸入todo項" style={{marginRight:'10px'}} onKeyUp={this.handleKeyUp} />
                        <button onClick={this.handleAdd}>點擊添加</button>
                        <ul>
                            {this.state.items.map(function(item){
                                return <li>{item.text}</li>;
                            })}
                        </ul>
                    </div>            
                    );
            }
        };

ReactDOM.render(
    <App />, 
    document.getElementById('example')
    );
    </script>
</head>

<body>

    <div>測試</div>
    <blockquote id='example'></blockquote>


</body>

</html>
相關文章
相關標籤/搜索