2016-04-27 73 views
2

我正在學習redux並作出反應。我決定運行一個簡單的「壓力測試」,讓我們說15k行的生成組件(我希望我做對了)。React redux生成的無狀態組件性能

所以我有無國籍的組件接收共同的道具,例如'年'。我想克隆9000多次無狀態組件並更新它們。例如,將其從2016年更改爲2015年的道具(年)。

我在我的測試項目中構建了這個組件,它工作正常,但響應速度慢,特別是在IE 11中。我是新來的反應+ redux,也許我做了一些事情在我的代碼錯誤。

正如不和諧聊天室的建議我已經加入到我的網頁組件:

 

    shouldComponentUpdate(nProps, nState) { 
     return nProps.year != this.props.year; 
     } 

這確實有點幫助。但它仍然很慢。

同樣作爲相關的問題 - 可以使用lodash.assign()來更新我的狀態嗎? 另外我使用的是打字稿,它似乎沒有爲Object.assign()內置的polyfill;這就是爲什麼我決定嘗試點贊。

因此,這裏是我的首要基礎組件app.tsx:

import * as React from 'react'; 
import {bindActionCreators} from 'redux'; 
import {connect} from 'react-redux'; 
import * as pageActions from '../actions/page'; 

import User from '../components/user/User'; 
import Page from '../components/page/Page'; 

class App extends React.Component<any, any> { 

    render() { 
    const { user, page } = this.props; 
    const { setYear } = this.props.pageActions; 

    return (
     <div> 
     <User name={user.name} /> 
     <Page photos={page.photos} year={page.year} setYear={setYear} /> 
     </div> 
    ); 
    }; 
} 

function mapStateToProps (state) { 
    return { 
    user: state.user, // (1) 
    page: state.page // (2) 
    }; 
} 

function mapDispatchToProps(dispatch) { 
    return { 
    pageActions: bindActionCreators(pageActions, dispatch) 
    }; 
} 

export default connect(
    mapStateToProps, 
    mapDispatchToProps 
)(App); 

這是我第減速機:

import {assign} from 'lodash'; 


const INITIAL_STATE = { 
    year: 2016, 
    photos: [] 
}; 

function pageReducer(state = INITIAL_STATE, 
         action = {type: '', payload: null}) { 
    switch (action.type) { 
    case 'SET_YEAR': 

    return assign({}, state, {year: action.payload}); 
    default: 
     return state; 
    } 
} 

export default pageReducer; 

和頁面組件:

import * as React from 'react'; 
import {range} from 'lodash'; 

let StatelessSpan: React.StatelessComponent<any> = (props) => (
    <span>{props.year} </span> 
); 

class Page extends React.Component<any, any> { 

    constructor(props) { 
    super(props); 
    } 

    private onYearBtnClick = (e) => { 
    this.props.setYear(+e.target.innerText); 
    }; 
    shouldComponentUpdate(nProps, nState) { 
    return nProps.year != this.props.year; 
    } 

    render() { 
    const {year, photos} = this.props; 

    let years = range(15000).map((value, index) => { 
     if(index % 4===0){ 
     return <StatelessSpan key={index} year={year} />; 
     } 
     return <span key={index}>i am empty</span> 
    }); 

    return <div> 
     <p> 
     <button onClick={this.onYearBtnClick}>2016</button> 
     <button onClick={this.onYearBtnClick}>2015</button> 
     <button onClick={this.onYearBtnClick}>2014</button> 
     </p> 
     {years} 
    </div>; 
    }; 
} 

export default Page; 

人告訴我innerText是實驗性的和非穩定的,所以我將它改爲textContent。在IE中仍然有延遲。

+0

恕我直言,這個練習聽起來是任意的和不切實際的。是什麼讓你選擇15k行?你會考慮什麼樣的響應水平_好?也許嘗試[Chrome JS分析](https://developer.chrome.com/devtools/docs/cpu-profiling)來確定性能瓶頸。 – adamb

+0

它可能聽起來是隨意的,但我有一個真正的角度應用,當它可能在Dom中有200個和更多元素並且可以接收相同的道具時,而不是像這個例子中的一個道具,但是10個道具或更多。我認爲,響應能力水平低於50毫秒。 – truedrog

+0

如果使用不同的Object.assign實現替換lodash的賦值函數,會發生什麼情況?你有沒有試過https://www.npmjs.com/package/object-assign? – matthewmatician

回答

1

React/Redux可能是編寫應用程序的最佳方式,但重要的是要理解優雅有時會以性能問題爲代價。幸運的是,採取優雅的解決方案並使其性能優於其他方法要容易得多。

我可以爲你的React和Redux拋出一堆性能優化技巧,但你可能會優化錯誤的東西。您需要分析您的應用,並找出您遇到的性能問題。

您可能會覺得這段對話非常有幫助:https://www.youtube.com/watch?v=5sETJs2_jwo。 Netflix已經能夠以非常緩慢的React開始,並且真正讓事情變得超快速而不會讓事情變得糟糕。

+0

好吧,我沒有600mhz的單核心設備,我應該改述我的問題。 在更新10k簡單跨度文本時,預計會出現滯後性能,而沒有任何邏輯IN反應?我在純js中構建了相同的測試,瓶頸是渲染和重新渲染。 現在,當我在React中做同樣的事情時,我的分析器顯示我的反應是做一些緩慢的事情(更新虛擬DOM可能?)。 那麼,用這種方式來測試反應是否值錢? – truedrog

+0

如果您希望我可以仔細查看您的代碼。隨意給我一個完整的例子,我會盡我所能去看看我是否可以多做點事情。 – matthewmatician