Immutable详解以及搭配react进行性能优化

当前的JavaScript语言存在的两个重要问题

JavaScript语言对于对象和数组,采用了引用赋值的方式,这样做的好处,就是节省了内存,我们称这样的方式是Mutable。但是这也是一切问题的万恶之源。当一个项目越来越复杂的时候,Mutable带来的内存优势,几乎就是个鸡肋般的存在了。

var a = { name: 'mapbar_front', age: 27 };
var b = a;
b.name = 'web_front';
console.log(a);//我们发现a对象也跟着改变。

第二个问题:
虽然我们可以进行shadowCopy(浅拷贝)和deepCopy(深拷贝),但是这样会造成CPU和内存的浪费。

Immutable就是来解决这样的问题的。

Immutable Data

什么是Immutable Data,就是一旦被创建,它就不可变的一种数据结构。

对Immutable对象的任何操作(添加、修改、删除)都会生成一个新的Immutable对象。

Immutable的实现原理是——Pressistent Data Structrue(持久化数据结构),也就是使用旧数据创建新数据的时候,旧数据不变并且可以使用。

deepCopy也是一种常用的操作,为了解决它浪费性能的问题,Immutable使用了一种Structural Sharing结构共享的方式。也就是创建新的对象的时候,只改变受影响的节点,其他节点使用共享的方式进行数据存储。
这里写图片描述

Immutable.js

Immutable.js是解决JavaScript的引用类型存在的问题的一种解决方案,作为一个js库,它主要有这么几个核心点。

第一、重要的几个数据类型:

  1. Map:键值对集合,对应Object。
  2. List:可重复的有序列表。对应Array。
  3. Set:不重复并且无序的列表。

第二、容易比较:

var map1 = Immutable.map({ a: 1,b: 1,c: 1 });
var map2 = Immutable.map({ a: 1,b: 1,c: 1 });
console.log(map1 === map2);//返回false。

使用 is 进行“值”比较。

var map1 = Immutable.map({ a: 1,b: 1,c: 1 });
var map2 = Immutable.map({ a: 1,b: 1,c: 1 });
Immutable.is(map1, map2);//true

第三、Immutable.fromJs(),把一个js对象转化为Immutable对象。Immutable.toJs(),把一个Immutable对象转化为js对象。

var $$list = Immutable.fromJS([1,2,3]);
var list = Immutable.toJS($$list);

第四、List()以及Map()用来创建List和Map类型的Immutable对象

const plainArray = [ 1, 2, 3, 4 ]
const listFromPlainArray = List(plainArray)

第五、isList()、isMap()。判断类型。

List.isList([]); // false
List.isList(List()); // true

搭配react进行性能优化

在react中,进行性能优化的方面,主要是在 shouldComponentUpdate 这个周期函数中,在默认的情况下,它总是会返回一个true,执行render方法,并且进行 virtrue DOM比较,但是这里往往进行了很多无用的渲染,并最终成为react的性能瓶颈。

当然我们也可以在 shouldComponentUpdate() 中使用使用 deepCopy 和 deepCompare 来避免无必要的 render(),但 deepCopy 和 deepCompare 一般都是非常耗性能的。

Immutable 则提供了简洁高效的判断数据是否变化的方法,只需 === 和 is 比较就能知道是否需要执行 render(),而这个操作几乎 0 成本,所以可以极大提高性能。修改后的 shouldComponentUpdate 是这样的:

import { is } from 'immutable';

shouldComponentUpdate: (nextProps = {}, nextState = {}) => {
  const thisProps = this.props || {}, thisState = this.state || {};

  if (Object.keys(thisProps).length !== Object.keys(nextProps).length ||
      Object.keys(thisState).length !== Object.keys(nextState).length) {
    return true;
  }

  for (const key in nextProps) {
    if (!is(thisProps[key], nextProps[key])) {
      return true;
    }
  }

  for (const key in nextState) {
    if (thisState[key] !== nextState[key] || !is(thisState[key], nextState[key])) {
      return true;
    }
  }
  return false;
}
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值