2015-09-11 10 views
5

私は大きなテーブルを描く必要があります。実際には大きくはないが、約400x400のセルを描画する必要があります。しかしReactは遅すぎるので、セルをクリックするたびにセルが更新され、このアップデートには同じ時間がかかります。どのようにそれをスピードアップするための任意の提案?あるいは、Reactはそのようなタスクに適したツールではありませんか?React.jsと大きなテーブル

ここ

は(表のわずかに減少サイズ)の例である:私はコンソールで、あなたの結果を検討している間 https://jsfiddle.net/69z2wepo/15731/

var ROWSC = 400; 
var COLSC = 100; 

var Hello = React.createClass({ 
    getInitialState: function() { 
     return { 
      t: { "1-1": 'c' } 
     }; 
    }, 
    clicked: function (k) { 
     var t = this.state.t; 
     t[k] = t[k] ? 0 : 'c'; 
     this.setState({ t: t }); 
    }, 
    render: function() { 
     var items = []; 
     for (var r = 0; r < ROWSC; r++) { 
      var cols = []; 
      for (var c = 0; c < COLSC; c++) { 
       var k = ''+r+'-'+c; 
       cols.push(<td key={c} onClick={this.clicked.bind(this,k)} className={this.state.t[k]}>&nbsp;</td>); 
      } 
      items.push(<tr key={r}>{cols}</tr>); 
     } 
     return <table> 
      {items} 
      </table> 
     </div>; 
    } 
}); 

React.render(<Hello name="World" />, document.getElementById('container')); 
+1

これはO(n^2)、400 * 100はそれほど大きくないが、まだそれがあることがわかります。あなたが50 * 50でそれを減らすと、あなたはすぐにその違いを見るでしょう。このリンクで興味深い速度の比較がありますが、それでも他のものよりも反応が速いです:https://www.codementor.io/reactjs/tutorial/reactjs-vs-angular-js-performance-comparison-knockout –

答えて

2

は、すべてを再レンダリング反応するが、パフォーマンスの問題の存在下で、 更新に除外するためにどの部品コンポーネントツリーの を決定するためにshouldComponentUpdate機能を使用することが可能です。我々は唯一の この行が更新されていることを確認することができますに更新が発生した行の追跡を開始した場合、あなたの例では

は、一つだけ一度に更新することができ行、そう あります。まず、フックを置くことができる テーブル行をラップする新しいコンポーネントを導入する必要があります。

var Row = React.createClass({ 
    shouldComponentUpdate: function(nextProps) { 
     return nextProps.mustUpdate; 
    }, 
    render: function() { 
     return <tr>{this.props.children}</tr>; 
    } 
}); 

その後、我々はさらに

items.push(
    <Row key={r} 
     mustUpdate={this.state.lastUpdatedRow === r}> 
     {cols} 
    </Row>); 

のようにそれを使用することができ、それはあまりにもすべてのこれらの細胞を再レンダリングする廃棄物のように思えるので、私たちはテーブルセルをラップ さらに別のコンポーネントを導入することができます。

var Cell = React.createClass({ 
    shouldComponentUpdate: function(nextProps) { 
     return this.props.selected !== nextProps.selected; 
    }, 
    render: function() { 
     var props = this.props; 
     return (
      <td onClick={props.onClick.bind(null, props.col, props.row)} 
       className={props.selected ? 'c' : ''}>&nbsp; 
      </td> 
     ); 
    } 
}); 

これにより、更新プログラムのパフォーマンスが大幅に向上します。あなたの特定の問題にまだ十分に対応していないのであれば、Reactはあなたのユースケースにとって理想的ではないかもしれません。 これは、Reactプログラムを最適化することの本質であり、コンポーネントをより小さな コンポーネントに分割し、実際に変更された部分だけが更新されていることを確認します。

+0

'shouldComponentUpdate'でコンポーネントにマークアップを抽出すると速度は大幅に向上しましたが、jQueryの実装よりもまだ遅いです。だから出てくる反応はここには当てはまらない。 – Dfr

+1

@Dfr大丈夫です。説明のために、Reactの生のDOM操作にフォールバックする方法を示す同じ例を示します。これは、生DOM操作が最も理にかなっているか、別のDOMライブラリと統合する必要がある場合に、コンポーネントに特定のパフォーマンス特性がある場合に役立ちます。 https://jsfiddle.net/treap/yoLhbzsj/ – Heap

0

、私は次のように各jsfiddle実行時にポップアップ気づい:

You are using the in-browser JSX transformer. Be sure to precompile your JSX for production - http://facebook.github.io/react/docs/tooling-integration.html#jsx

ブラウザー内のJSXトランスを使用すると、パフォーマンスへの影響についてドキュメントで警告されています。

おそらく、JSXのプリコンパイルで別のテストをやって

The in-browser JSX transformer is fairly large and results in extraneous computation client-side that can be avoided. Do not use it in production

はあなたにこのが反応のために良いユースケースであるかどうかについてのより良いアイデアを与えるだろう。

+0

完全性のために非JSXの亜種:https://jsfiddle.net/69z2wepo/15760/ – Dfr

0

2つのこと:

はその遅さを避けるためにJSXをプリコンパイルすることを確認します。 (JSFトランスフォーマを使用していますが、実際にJSXをプロダクション用にプリコンパイルしてください)

クリック設定状態の単独のコンポーネントとして実装されているため、テーブル全体を再処理する必要があります(setStaterenderをトリガーしてテーブルDOMを再構築するため)。多くの場合、各テーブルセルを表すComponentを作成することで避けられますが、clicked関数では、setState Helloの場合、クリックしたセルでsetStateを呼び出すだけで、変更されたセルだけが再レンダリングされます。

これは初期レンダリングには役立ちませんが、クリックによるUI更新のスピードアップ。デフォルトでは

関連する問題