与许多textareas(但不是文本输入字段)反应缓慢

Ess*_*seb 5 reactjs

有很多textareas,我(不可否认的大)形式变得迟钝.

但是,使用文本输入字段,一切都很顺畅.

我创建了两个最小化的测试用例,一个用textareas,另一个用输入字段.单击切换按钮以显示/隐藏组以查看问题.至少在Chrome上,该组在textarea版本中切换的速度非常慢.

2500 textareas:http://jsbin.com/wudujusoji/edit? html,js, output

2500个文本输入字段:http: //jsbin.com/rezudotojo/edit?html,js,output

我在这做错了什么?textarea和文本输入字段版本的性能大致相同吗?

Bri*_*and 8

让我们使测试合理,并将shouldComponentUpdate添加到每个中的Input组件中.

var Input = React.createClass({
  shouldComponentUpdate: function(nextProps){
    return nextProps.value !== this.props.value;
  },
Run Code Online (Sandbox Code Playgroud)

console.time() 如果你想测量一些数学或类似的东西是好的,但要真正看到这里发生了什么,我们需要使用探查器.

我们将从<input>s 开始.我这样做了几次,对我来说总是大约14ms.

右侧标有"(程序)"的灰色栏是浏览器在JS返回后自行完成的工作.这里需要大约17ms来准备渲染.在那之后闲置,除了绘画之外什么也没做.很酷,考虑到元素的数量,这还不错.

在chrome dev工具中分析输入示例

textarea更有趣.这些中的反应平均值大约为30ms,考虑到它是开发构建,这很好.我不知道为什么chrome需要500ms才能处理这些变化.

在chrome dev工具中分析textarea示例 textarea的另一个档案 另一个textarea个人资料

我认为React必须做一些事情才能导致这种情况,所以我(hackily)添加了一个MutationObserver.

var mObserver = new MutationObserver(function(mutations) {
  mutations.forEach(function(mutation, i) {
    console.log('mutation ' + i + ': ' 
                + mutation.type 
                + ', at ' 
                + mutation.target.parentNode.tagName 
                + ' > ' 
                + mutation.target.tagName 
                + '[' 
                + [].indexOf.call(mutation.target.parentNode.children, mutation.target) 
                + ']'
                + ', on attribute ' + mutation.attributeName
                + ', from ' + mutation.oldValue 
                + ' to ' + mutation.target.getAttribute(mutation.attributeName)
               );

  });    
});
var moConfig = { attributes: true, childList: true, characterData: true, subtree: true };

React.render(React.createElement(Editor, null),
    document.querySelector('.editor'), 
    function(){
        var root = document.getElementById('root');
        if (!root) throw new Error('no root');
        mObserver.observe(root, moConfig);
    }
);
Run Code Online (Sandbox Code Playgroud)

点击按钮时会显示:

mutation 0: attributes, at DIV > DIV[0], on attribute class, from null to category
mutation 1: childList, at DIV > BUTTON[0], on attribute null, from null to null
Run Code Online (Sandbox Code Playgroud)

所以是的...我非常确定更改div的类名和按钮的文本内容会导致它花费500ms更新.我猜这是所有花在尝试布局textareas.


与往常一样,"当我做X时渲染2,000个节点"的答案是不渲染2,000个节点; X(例如React)无关紧要.

实际上,这里略超过5000,但谁在数呢?