React redux 生成的无状态组件性能
React redux generated stateless components perfomance
我正在学习 redux 和 React。我决定 运行 一个简单的 "stress test",假设有 15k 行生成的组件(我希望我做对了)。
所以我有无状态组件,例如接收通用道具 'year'。我想将这个无状态组件克隆 9000 多次并更新它们。例如,将 prop(year) 从 2016 更改为 2015。
我在我的测试项目中构建了这个组件并且它正在运行,但响应缓慢,尤其是在 IE 11 中。我是 react+redux 的新手,也许我在我的代码中做错了什么。
按照不和谐聊天室的建议,我已将其添加到我的页面组件中:
shouldComponentUpdate(nProps, nState) {
return nProps.year != this.props.year;
}
这确实有点帮助。但是还是很慢。
还有相关问题 - 可以使用 lodash.assign() 来更新我的状态吗?
我也在使用打字稿,它似乎没有为 Object.assign(); 内置的 polyfill;这就是我决定尝试 lodash 的原因。
所以这是我的顶级基础组件 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 仍然有延迟。
React/Redux 可能是编写应用程序的最佳方式,但重要的是要了解优雅有时会以性能问题为代价。幸运的是,采用优雅的解决方案并使其性能比其他方式更容易。
我可以向你抛出一堆关于 React 和 Redux 的性能优化技巧,但你可能优化了错误的东西。您需要分析您的应用并找出您 运行 遇到的性能问题。
您可能会发现此演讲非常有帮助:https://www.youtube.com/watch?v=5sETJs2_jwo。 Netflix 已经能够从非常慢的 React 开始,并真正让事情变得超快而不会把事情弄得一团糟。
我在这里找到了这个讨论:https://twitter.com/mweststrate/status/720177443521343488
所以这部分回答了我关于性能的问题,并很好地了解了这两个库如何处理我的案例。
我正在学习 redux 和 React。我决定 运行 一个简单的 "stress test",假设有 15k 行生成的组件(我希望我做对了)。
所以我有无状态组件,例如接收通用道具 'year'。我想将这个无状态组件克隆 9000 多次并更新它们。例如,将 prop(year) 从 2016 更改为 2015。
我在我的测试项目中构建了这个组件并且它正在运行,但响应缓慢,尤其是在 IE 11 中。我是 react+redux 的新手,也许我在我的代码中做错了什么。
按照不和谐聊天室的建议,我已将其添加到我的页面组件中:
shouldComponentUpdate(nProps, nState) { return nProps.year != this.props.year; }
这确实有点帮助。但是还是很慢。
还有相关问题 - 可以使用 lodash.assign() 来更新我的状态吗? 我也在使用打字稿,它似乎没有为 Object.assign(); 内置的 polyfill;这就是我决定尝试 lodash 的原因。
所以这是我的顶级基础组件 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 仍然有延迟。
React/Redux 可能是编写应用程序的最佳方式,但重要的是要了解优雅有时会以性能问题为代价。幸运的是,采用优雅的解决方案并使其性能比其他方式更容易。
我可以向你抛出一堆关于 React 和 Redux 的性能优化技巧,但你可能优化了错误的东西。您需要分析您的应用并找出您 运行 遇到的性能问题。
您可能会发现此演讲非常有帮助:https://www.youtube.com/watch?v=5sETJs2_jwo。 Netflix 已经能够从非常慢的 React 开始,并真正让事情变得超快而不会把事情弄得一团糟。
我在这里找到了这个讨论:https://twitter.com/mweststrate/status/720177443521343488
所以这部分回答了我关于性能的问题,并很好地了解了这两个库如何处理我的案例。