zoukankan      html  css  js  c++  java
  • 发布高性能迷你React框架anu

    anu, 读作[安努],原意为苏美尔的主神。

    anu是我继avalon之后又一个新框架(github仓库为https://github.com/RubyLouvre/anu, 欢迎加星与试用)

    此框架的创立之意有三:

    1. 提升性能, 虽然React的性能相对于传统的MVVM框架是很厉害了,但近几年冒出来的diff算法比官方版更优秀,官方版积重难返,很难短时期吸收这些成果。anu则小船好调头,第一时间收纳其中。性能是王道。天下武功,唯快不破。

    2. 压缩体积。 React+React-dom加起来有三万多行,这么大的体量任何code splitting与按需加载技术都无能为力,因此我们需要迷你版的体积。

    3. 卓越的浏览器兼容性。 React在生产环境中没有用到什么新式偏门的API,因此本来就可以兼容到IE8之下。兼容性越好,我们的后顾之忧越少。

    这三个特点都是为扩展React的通用性而努力。

    在开发过程中,先是参考react-lite搞了一个版本,遇到问题后又根据preact搞了一版,第二版成功后命名为qreact,已经在公司的项目中用。

    第二版的特点是preact改+preact.compat改+自创事件系统+diff机制改。反正经过这次研发后,我们已经掌握了React的许多机制,但是还没有吃透preact的diff。

    不过腾出时间来后,开始第三版,就是现在开源出来的anu,它大部分机制是自创的,diff机制采取react-lite。性能比第二代qreact强许多。

    以下是成品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>
  • 相关阅读:
    QTP中选中页面提示ActiveX无法显示
    今天的突然奇想——我想自己做个bug管理工具
    问题解决:Target runtime Apache Tomcat v6.0 is not defined
    java异常类子类和父类的关系
    android与后台服务器连接:android.os.NetworkOnMainThreadException
    struts初探
    eclipse启动Tomcat问题:严重: Socket accept failed
    eclipse启动报错:java was started but returned code=13
    console.log是异步么?
    字符串函数 replace() 方法妙用
  • 原文地址:https://www.cnblogs.com/libin-1/p/6956484.html
Copyright © 2011-2022 走看看