1.redux修改数据引起的性能问题
上一篇redux文章中讲到了,我们在reducer中重新修改数据的时候,需要复制一份state(浅拷贝),防止我们原本的数据被修改,之后进行数据修改。
我们在文件中的代码如下所示:
function reducer(state = defaultState, action) {
switch(action.type) {
case actionTypes.CHANGE_TOP_BANNERS:
return {
...state,topBanners:action.topBanners}
default:
return state;
}
}
如上代码,我们可以看出来,当我们需要将redux中保存的state里面的topBanners数据进行修改的时候,我们先是对整个state进行了一次浅拷贝,之后我们才对topBanners进行了赋值修改。
那么当我们state数据特别多的时候,每一次都需要浅拷贝state就造成了性能浪费。
2.数据的可变性引起的一些问题
首先对于我们学习过js的同学,都会知道js中引用值共享的问题。
now,举个例子吧。
const info = {
name:'kjh',
age:20
}
const obj = info;
obj.name = "康家豪";
console.log(info.name); //"康家豪"
而我们解决这种问题的时候,就喜欢使用一个浅拷贝。
const info = {
name:'kjh',
age:20
}
const obj = {
...info};
obj.name = "康家豪";
console.log(info.name); //kjh
但是这种浅拷贝和我们上面说到的问题一样,如果说我们的info对象过于庞大,而我却只想修改一个name导致整个info对象都要拷贝一次,这样会带来性能问题以及内存浪费。
3.认识ImmutableJS
- 为了解决上面的问题,出现了Immutable对象的概念:
- Immutable对象的特点是只要修改了对象,就会返回一个新的对象,旧的对象不会发生改变。
- 但是这样的方式就不会浪费内存了嘛?
- 为了节约内存,又出现了一个新的算法:Persistent Data Structure(持久化数据结构或一致性数据结构)。
4.ImmutableJS的使用
ImmutableJS map的使用
// immutableJS的使用
const IM = Immutable;
const info = {
name:"kobe",
age:30,
friend:{
name:"codewhy",
age:29
}
}
const infoIM = IM.Map(info);
const obj = infoIM;
const newInfo = infoIM.set("name","康家豪");
console.log(obj.get('name')); //kobe
console.log(newInfo.get('name')); //康家豪
ImmutableJS list的使用
const names = ['abc','cba','nba'];
const namesIM = IM.List(names);
const arrIM = namesIM.set(0,"why");
console.log(namesIM.get(0)); //abc
console.log(arrIM.get(0)); //why
ImmutableJS 的使用(3)
const IM = Immutable;
const info = {
name:"kobe",
age:30,
friend:{
name:"codewhy",
age:29
}
}
const infoIM = IM.fromJS(info);
//fromJS 会把JS里面所有的对象都转化为Immutable对象
console.log(infoIM.get('friend'))
5.使用ImmutableJS对项目进行优化
首先安装immutable.js
yarn add immutable
因此我们可以使用ImmutableJS对每一个页面模块的reducer.js文件进行优化。
recommend/store/reducer.js 未优化前
import * as actionTypes from './constants';
const defaultState = {
topBanners: []
}
function reducer(state = defaultState, action) {
switch(action.type) {
case actionTypes.CHANGE_TOP_BANNERS:
return {
...state,topBanners:action.topBanners}
default:
return state;
}
}
export default reducer;
recommend/store/reducer.js 优化后
import {
Map } from 'immutable'
//Map 相较于 fromJS更加高性能
import * as actionTypes from './constants';
const defaultState = Map({
topBanners: []
})
function reducer(state = defaultState, action) {
switch(action.type) {
case actionTypes.CHANGE_TOP_BANNERS:
return state.set("topBanners",action.topBanners)
default:
return state;
}
}
export default reducer;
使用:state.recommend.get(“topBanners”)
之后我们需要优化根目录下的reducer
安装 redux-immutable
import {
combineReducers } from 'redux-immutable';
import {
reducer as recommendReducer } from '../pages/discover/c-pages/recommend/store';
const cReducer = combineReducers({
recommend:recommendReducer
})
export default cReducer;
------------------------------------------------------------------------------------------------------------------------------------
最近很喜欢的一句话:从来如此,便是对的吗?
------------------------------------------------------------------------------------------------------------------------------------