资讯专栏INFORMATION COLUMN

Immutable

Coly / 3329人阅读

摘要:如果实现了结构共享,每次的新值共享内部结构以大幅减少内存占用。这意味着,如果对一个进行赋值次,并不会创建倍大小的内存占用数据。消除了流经系统的精神负担。代价是编写风格将颠覆式的完全不同。会带来很多无必要的渲染并成为性能瓶颈。

Part01 Immutable由何而生

说immutable之前,首先看下什么是mutable。js在原生创建数据类型即是mutable,可变的。
const只是浅层次的防篡改,层级一深就没辙了。

js在创建变量、赋值后是可变的。除了基本类型,其他的引用类型,通过变量地址来共享。
改变了obj1.a的值,同时也会改变obj.a的值。其实改变的是同一个对象引用。这样共享地址来共享值的好处是节省内存,坏处是稍微不注意就会导致改A坏B的棘手问题。

Deep Copy?No!

一般的解法就是使用深拷贝而非浅拷贝,生成一份基本类型值完全相同但是没有共享地址的数据,除了浪费内存之外,深拷贝复杂引用类型时需要深度遍历,这样的做法在React这样频繁更新数据和对数据更新性能有要求的场景,深拷贝是一个不优雅不推荐,say no的选择。
那怎么做呢,这个时候Immutable就可以闪亮登场解决这个问题,为什么呢?

Part02 Immutable是个什么

相对于mutable,Immutable就是在创建变量、赋值后便不可更改,若对其有任何变更,就会回传一个新值

Immutable只是一个定义,有各种实现,Immutable.js就是facebook工程师实现js的Immutable历时三年的烧脑之作。甚至有些语言天生就是不可变数据结构,比如国内react的早期先驱题叶极力推崇的ClojureScript。
每次返回新值,大家可能会觉得性能也并不好啊,又占内存之类的。如果实现了结构共享,每次的新值共享内部结构以大幅减少内存占用。这意味着,如果对一个Immutable进行赋值1000次,并不会创建1000倍大小的内存占用数据。

与原生JS的mutable语义强烈冲突

除非从零开始一个项目,不然这种使用导致我们可能用混,第三方库也只支持原生js对象。
我们需要采用一些手段来规避用混。

使用类型系统,TypeScript或Flow。消除了Immutable流经系统的精神负担。代价是编写风格将颠覆式的完全不同。

隐藏有关数据结构的详细信息。如果您在系统的特定部分使用Immutable.js,请不要在其外部进行任何操作直接访问数据结构。一个很好的例子是Redux,它是单原子app状态。如果app状态是Immutable.js对象,请不要强制React组件直接使用Immutable.js的API。

https://codesandbox.io/s/yq872yrlnx

真正的结构共享vs对象代理的伪实现

结构共享是指没有改变的数据共用一个引用,这样既减少了深拷贝的性能消耗,也减少了内存。

extend https://reactjs.org/docs/update.html

Part03 怎么用 与React搭配使用,关键点是shouldComponentUpdate

熟悉 React 的都知道,React 做性能优化时有一个避免重复渲染的大招,就是使用 shouldComponentUpdate(),但它默认返回 true,即始终会执行 render() 方法,然后做 Virtual DOM 比较,并得出是否需要做真实 DOM 更新,尽管React的虚拟算法复杂度已经有了很多优化,但是在大规模组件更新时,依然会是个不必要的损耗。会带来很多无必要的渲染并成为性能瓶颈。
我们常用的Purecomponent的秘密其实是在shouldComponentUpdate中做了前后state和props的浅比较,如果不小心组件props的引用问题,这里会导致出现很多Bug。
虽然第一层数据没变,但引用变了,就会造成虚拟 DOM 计算的浪费。
第一层数据改变,但引用没变,会造成不渲染,所以需要很小心的操作数据。

Object.assign可以实现不可变数据,唯一的就是性能问题 Part04 怎么实现 seamless-immutable

Object.freeze防止对象被修改
https://developer.mozilla.org...

function makeImmutable(obj, bannedMethods) {
  // 在对象上打上immutabilityTag标记即表示对象不可变
  addImmutabilityTag(obj);

  if (process.env.NODE_ENV !== "production") {
    // 让所有导致对象改变的方法在调用时抛出错误
    for (var index in bannedMethods) {
      if (bannedMethods.hasOwnProperty(index)) {
        banProperty(obj, bannedMethods[index]);
      }
    }
    // 冻结对象
    Object.freeze(obj);
  }
  return obj;
}

确保对象不可变的分三步:

打上immutabilityTag标记;

禁用会导致对象改变的方法;

冻结对象。

Immutable-js

精读 Immutable 结构共享 https://juejin.im/entry/59b5e...

深入探究Immutable.js的实现机制 https://juejin.im/post/5b9b30...

了解Clojure的持久变量 https://hypirion.com/musings/...

完结

(此文由PPT摘抄完成)PPT链接

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/99801.html

相关文章

  • Immutable源码解析与性能优化

    摘要:修改的节点和该父级链路上都变成新的对象显然是最优方案。如果你对比的两个中,一个被过,另一个数据又是由其衍生出来的,那效率将是最高的算法的原理与优化检测本地中是否存在已过当前对象字符串。 Immutable原理解析 简介 what is Immutable 1.不可变,一成不变的 2.对immutable数据的每次修改操作都会返回一个新的data 掏出一副老生常谈的图 showImg(h...

    233jl 评论0 收藏0
  • React-redux进阶之Immutable.js

    摘要:的优势保证不可变每次通过操作的对象都会返回一个新的对象丰富的性能好通过字典树对数据结构的共享的问题与原生交互不友好通过生成的对象在操作上与原生不同,如访问属性,。 Immutable.js Immutable的优势 1. 保证不可变(每次通过Immutable.js操作的对象都会返回一个新的对象) 2. 丰富的API 3. 性能好 (通过字典树对数据结构的共享) Immutab...

    孙淑建 评论0 收藏0
  • React系列之 Immutable

    摘要:原文地址什么是是指一旦被创建就不可以被改变的数据,通过使用不可变数据可以让我们很方便的去处理数据的状态变化检测等问题,而且让我们的程序变得更加的可预见怎么用大体使用深度转换和为和浅转换给倒数第一个赋值更多可以查看这里为什么要用其实从上面 原文地址:https://gmiam.com/post/react-... 什么是 Immutable Data ? Immutable Data 是...

    cc17 评论0 收藏0
  • 微信小程序开发实战——使用Immutable.js

    摘要:是开发的不可变数据集合。微信小程序无法直接使用进行调用需要对下载的代码进行修改才能使用。原因分析使用了模块化规范的实现很简单,先判断是否支持模块规范,存在则使用方式加载模块。通过测试,微信小程序运行环境并没有定义。 Immutable 是 Facebook 开发的不可变数据集合。不可变数据一旦创建就不能被修改,是的应用开发更简单,允许使用函数式编程技术,比如惰性评估。Immutable...

    邱勇 评论0 收藏0
  • 笔记, immutable-js 基础操作

    摘要:这篇文章是一些操作的整理目前只有基本的操作文档请查看使用过程中遇到的写法我会不会增加在后边当中不可变数据有点不适应需要借鉴一些中的内容更新六月份到十月份我们完成了不可变数据的重构配合简聊的巨大的单一可以整理出来一些常用的方法示例代码用的是 这篇文章是 immutable-js 一些操作的整理, 目前只有基本的操作:文档请查看: http://facebook.github.io/imm...

    alexnevsky 评论0 收藏0

发表评论

0条评论

Coly

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<