2016-01-19 44 views
1

我正在嘗試呈現具有反應js的項目列表。由於我的列表項目相對複雜,我創建了一個簡單的小提琴來陳述我的問題。每次將新元素推入列表時,ReactJS呈現列表的時間都會增加

fiddle

在我來說,我有職位的無限滾動和增加渲染時間與崗位走出的合理的渲染時間非常快的每一推。它以200-250毫秒開始,並在10次按下後推到500毫秒(每次推送有0-10個帖子)。

如何修復新增項目的渲染時間?或者它只是如何反應js工作。

這是我的主ReactComponent簡化。

React.createClass({ 
    shouldComponentUpdate: function (nextProps, nextState) { 
     return nextState.posts.length !== this.state.posts.length; 
    }, 
    getInitialState: function() { 
     return { 
      posts: [] 
     }; 
    }, 
    // getStream is bound to a scroll event handler. Simply, this function is called when user gets close to the end of page. 
    getStream: function() { 
     var self = this; 
     ... ajax call success: (jsonResult) ... 
     self.setState({ 
      posts: React.addons.update(self.state.posts, { $push: jsonResult }) 
     }); 
     ... end .... 
    }, 
    render: function() { 
     var self = this; 

     var postNode = this.state.posts.map(function (post, i) { 
      if (post.isActivity) { 
       return (<ReactActivity key={i}></ReactActivity>); 
      } 
      else { 
       return (<ReactStreamPost key={i}></ReactStreamPost>); 
      } 
     }); 

     return (<div> 
      {postNode} 
     </div>); 
    } 
    }); 

而ReactStreamPost和ReactStreamActivity在這一點上可以是無狀態組件。像

var ReactStreamPost = React.createClass({ 
    shouldComponentUpdate: function() { 
     return false; 
    }, 
    render: function() { 
     return (
      <div className="stream-post"> 
       <div className="post-topbar"> 
        <a href="#" className="display-name">Test USER</a> 
       </div> 

       <div className="post-inner-wrapper"> 
        <div className="post-owner-big"> 
         <div className="post-owner"> 
          <img className="profile-img" /> 
         </div> 
        </div> 
        <div className="post-content"> 
         <div className="post-header"> 
          <div className="post-owner"> 
           <img className="profile-img" /> 
          </div> 
          <div className="post-agt"> 
           <ReactAutoGenerateTitle></ReactAutoGenerateTitle> 
          </div> 
         </div> 
         <div className="post-title"> 
          <div> 
           <a href="#" className="display-name">Test USER</a><span> Post title</span> 
          </div> 
         </div> 
         <div className="attachments"> 
          attachments 
         </div> 

         <div className="post-actions"> 
          <div className="left-actions"> 
           <a href="#"> 
            <i className="icon icon-add-info"></i><span>Add info</span> 
           </a> 
          </div> 
          <div className="right-actions"> 
           <a href="#" className="toggler"> 
            <i className="icon"></i> 
            <span>x</span> 
           </a> 
           <a href="#" className="toggler"> 
            <i className="icon"></i> 
            <span>x</span> 
           </a> 
           <a href="#" className="share icon icon-share"></a> 
          </div> 
         </div> 

         <div className="post-comments"> 
          <div className="comment-block"> 
           <div className="commentor"> 
            <img /> 
           </div> 
           <div className="comment"> 
            <a href="#">Test USER</a><span>: </span><span>Comment test</span> 
           </div> 
           <div className="comment-date"> 
            <span>comment date</span> 
           </div> 
          </div> 

          <div className="comment-form"> 
           <div className="commentor"> 
            <img /> 
           </div> 
           <div className="text-area"> 
            <textarea rows="1" className="small"></textarea> 
           </div> 
           <div className="submit-comment"> 
            <a href="#" className="icon icon-send"></a> 
           </div> 
          </div> 
         </div> 
        </div> 
       </div> 
       <div className="post-date"> 
        <span>post date</span> 
       </div> 
      </div> 
     ); 
    } 
}); 
+0

您正在添加更多DOM元素,當然時間會增加。 –

+0

但是每次我給dom添加相同數量的元素。我知道每個狀態更新都會重新渲染,但這個代價對我來說似乎有點高。 – Azadrum

+0

請不要將數組索引用作子元素鍵。如果您使用的密鑰在列表中添加其他內容時不會更改,您將獲得更好的性能。 – rossipedia

回答

3

這是因爲每次你加入更多的元素時,整個列表被重新呈現,而且也包括了之前已經呈現列表項。

解決方法之一是將列表項放入其自己的組件中,並使用shouldComponentUpdate不重新呈現它。這仍然會增加時間,因爲它仍然需要檢查是否需要重新渲染,但增量不會那麼陡峭。工作小提琴here。您的排組件將如下所示: -

var Row = React.createClass({ 
    shouldComponentUpdate: function() { 
    return false; 
    }, 

    render: function() { 
    return (<li> <span> some < /span><span>more</span > <span> elements < /span></li >) 
    } 
}) 
+0

這是我在自己的實施中試圖做的事情,但要重新檢查它。並感謝你的例子。 – Azadrum

+0

https://jsfiddle.net/jain208/3jj5Loky/3/ - 這是兩個實現更新的小提琴。 :-) –

+0

但是,這種方法永遠不會有效,因爲您仍然渲染大量項目。理想的方法是僅顯示列表的子集。 –

相關問題