Javascript 在React中实现双向数据绑定的性能影响

Javascript 在React中实现双向数据绑定的性能影响,javascript,performance,reactjs,flux,Javascript,Performance,Reactjs,Flux,新来者的一个常见问题是,为什么双向数据绑定不是内置功能,通常的回答包括对单向数据流的解释,以及出于性能原因,双向数据绑定并不总是可取的想法。这是我想更详细地理解的第二点 我目前正在为(来自Apollo的新客户端状态管理工具)开发表单库。除了使用apollo链接状态而不是redux作为状态管理器之外,该概念与redux表单非常相似。(请注意,表单状态与域实体的状态分开存储,尽管可以选择使用实体来填充表单的初始状态。) 当用户对表单进行更改时,库会立即通过onChange处理程序更新存储。我曾考虑允

新来者的一个常见问题是,为什么双向数据绑定不是内置功能,通常的回答包括对单向数据流的解释,以及出于性能原因,双向数据绑定并不总是可取的想法。这是我想更详细地理解的第二点

我目前正在为(来自Apollo的新客户端状态管理工具)开发表单库。除了使用apollo链接状态而不是redux作为状态管理器之外,该概念与redux表单非常相似。(请注意,表单状态与域实体的状态分开存储,尽管可以选择使用实体来填充表单的初始状态。)

当用户对表单进行更改时,库会立即通过
onChange
处理程序更新存储。我曾考虑允许单个字段选择退出该行为,以防程序员担心性能,但后来我开始怀疑这何时会成为真正的性能问题。无论发生什么情况,浏览器都将触发
oninput
事件,因此我能想到的唯一性能考虑因素是存储是否随用户类型而更新。当然,执行一个变异比仅仅调用
setState()
会有额外的开销,但这实际上只相当于两个额外的函数调用。假设我没有使用apollo,只是调用了一个直接更新全局存储的函数——那么性能考虑是什么呢

我的想法是,如果一个表单要支持在用户在一个字段中键入时立即更新表单状态,那么它也可以对所有字段进行更新。用户一次只能键入一个字段,我不认为某些字段有时会使页面更快(可能可以忽略不计),而其他字段有时会使页面更慢。此外,我的库允许用户使用他们想要的任何输入组件,因此,如果程序员只需要较少的状态更新,他们可以编写一个组件来消除React的
onChange
事件或使用浏览器自己的
change
blur
事件的影响

我是不是遗漏了什么?我的库的用户在提交表单之前是否还有其他原因希望忽略特定字段的更改?或者更有用的选择是忽略对整个表单的更改(直到提交)

以下是我当前方法背后的基本概念的基本(大大简化)说明:

// defined in a globally-accessible module
const formState = {
    // This somehow causes any dependent form components to re-render
    // when state changes
    update(formName, updatedState) {
        ...
    }
}
export default formState

...
// UserForm.js:

export default class UserForm extends PureComponent {
    componentDidMount() {
        formState.userForm = {
            firstName: '',
            lastName: '',
        }
    }

    handleChange(e) {
        const { target } = e
        formState.update('userForm', { [target.name]: target.value })
    }

    //...

    render() {
        const { userForm } = formState
        return (
            <form onSubmit={this.handleSubmit}>
                <label for="name">Name</label>
                <input id="name" type="text" onChange={this.handleChange} value={userForm.name} />

                <label for="email">Email</label>
                <input id="email" type="email" onChange={this.handleChange} value={userForm.email} />
            </form>
        )
    }
}
//在全局可访问模块中定义
常量formState={
//这会以某种方式导致任何相关表单组件重新渲染
//当状态改变时
更新(formName,updatedState){
...
}
}
导出默认formState
...
//UserForm.js:
导出默认类UserForm扩展PureComponent{
componentDidMount(){
formState.userForm={
名字:'',
姓氏:“”,
}
}
手变(e){
常数{target}=e
update('userForm',{[target.name]:target.value})
}
//...
render(){
const{userForm}=formState
返回(
名称
电子邮件
)
}
}

最后,为了完整性,我应该提到,这其中还涉及一些API设计考虑因素。如果我没有提供选择退出自动双向绑定的选项,那么单个输入组件的设计可能会稍微简单一些。如果有人感兴趣,我可以发布详细信息。

2路数据绑定含义 从问题的第一部分开始,react不使用双向数据绑定有两个主要原因:

  • React应用程序中数据更改的单一真相来源,因此出现错误的可能性更小,调试更容易
  • 绩效效益
  • 在React中,我们可以通过将状态共享到一个公共父组件来在不同的子组件之间共享状态。更新共享状态时,所有子组件都可以更新自己。这是与表单相关的文档中的一个很好的例子

    谈到性能优势,在其他一些上下文(比如AngularJS)中,双向数据绑定通过观察者观察不同的元素来工作。对于少量元素来说,这听起来更容易(而且代码比React的单向数据流要少),但是随着UI组件/元素数量的增加,观察者的数量也会增加。在这种情况下,一个简单的改变就会导致许多观察者启动,以保持事情的同步。这使得性能有点慢。在React的情况下,由于只有单向数据流,因此更容易确定哪些组件需要更新

    处理状态更新 转到问题的第二部分,您的状态库将数据提供给表单组件,导致任何依赖组件在状态更改时更新,sweet。以下是我的想法:

    我在考虑允许单个字段选择不使用该选项 程序员关心性能时的行为,但是 然后我开始想这什么时候才是真正的表演 问题

    商店更新本身会很快发生。JavaScript运行速度非常快,经常导致瓶颈的是DOM更新。因此,除非同一页面上有数百个相关表单元素,并且所有这些元素都得到更新,否则您就没事了

    让我们假设我没有使用阿波罗,只是打电话给 直接更新某个全局存储的函数-该函数的作用是什么 那么性能方面的考虑呢

    我认为这不会有什么显著的区别

    我的想法是,如果一个表单将支持imm