Immutable?Mutative比Immer。js快10
大家好,很高兴又见面了,我是高级前端进阶,由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!
高级前端进阶1。什么是不可变性(ImmutableData)?
ImmutableData一旦创建,就不能被更改。对Immutable对象的任何修改、添加或删除操作都会返回一个新的Immutable对象。
什么是不可变对象?图片来源:AlamyStockPhoto
Immutable实现原理是持久化数据结构(PersistentDataStructure),也就是使用旧数据创建新数据时,要保证旧数据同时可用且不变。
为了避免深度拷贝(deepCopy)把所有节点都复制一遍带来的性能损耗,Immutable使用了共享结构(StructuralSharing),即如果对象树中一个节点发生变化,只修改这个节点和受它影响的父节点,其它节点则进行共享。如下动图所示:
2。Immer介绍?2。1什么是Immer?
Immer简化了不可变数据结构的处理。
Immer可用于任何需要使用不可变数据结构的上下文。例如与Reactstate、React或Reduxreducer或配置管理相结合。不可变数据结构允许更改检测:如果对对象的引用没有更改,则对象本身没有更改。此外,它使克隆更加容易:不需要复制数据树的未更改部分,并且在内存中与相同状态的旧版本共享。constupdatedUser{。。。User,Rest展开操作User来获取新的更新后的User对象,即updatedUsered:{。。。User。ed,school:{。。。User。ed。school,name:B}}}
一般来说,这些好处可以通过确保您永远不会更改对象、数组或映射的任何属性,而是始终创建一个更改的副本来实现。在实践中,这会导致代码编写起来非常麻烦,而且很容易意外地违反这些约束。
Immer将通过解决这些痛点帮助您遵循不可变数据范式:Immer将检测意外突变并抛出错误Immer将消除对不可变对象创建深度更新时所需的典型样板代码的需要:如果没有Immer,则需要在每个层级手动制作对象副本。使用Immer时,会对draf对象进行更改,draf对象会记录更改并负责创建必要的副本,而不会影响原始对象。使用Immer无需学习专用API或数据结构。2。2Immer如何工作?
使用Immer,会将所有更改应用到临时草稿,它是currentState的代理。完成所有更新后,Immer将根据对草案状态的改变生成nextState。这意味着可以通过简单地修改数据来与数据交互,同时保留不可变数据的所有好处。
使用Immer就像拥有一个私人助理。助理拿了一封信(当前状态)并给了您一份副本(草稿)以记下更改。完成后,助手会拿走你的草稿并为你生成最终的一封信(下一个状态)。2。3Immer使用?constbaseState〔基础、原始state{title:LearnTypeScript,done:true},{title:TryImmer,done:false}〕
假设有上面的基本状态,需要更新第二个待办事项,并添加第三个,同时不想改变原始的baseState,同时避免深度克隆(以保留第一个待办事项)。2。3。1不使用Immer
如果没有Immer,将不得不小心地浅复制受更改影响的状态结构的每一层。constnextStatebaseState。slice(数组浅复制nextState〔1〕{replaceelement1。。。。。。nextState〔1〕,withashallowcloneofelement1done:true。。。combinedwiththedesiredupdate}nextState被深度拷贝,push方法是安全的butdoingthesamethingatanyarbitrarytimeinthefuturewouldviolatetheimmutabilityprinciplesandintroduceabug!nextState。push({title:Tweetaboutit})2。3。2使用Immer
使用Immer,此过程更加直接。可以利用produce函数,它将开始的状态作为第一个参数传递。produce将负责所有的复制操作,并通过冻结数据来防止未来的意外修改。importproducefromimmerconstnextStateproduce(baseState,draft{通过produce方法操作draft〔1〕。donetruedraft。push({title:Tweetaboutit})})3。什么是Mutative?
Mutative是一个用于高效、不可变更新的JavaScript库,默认情况下比Immer快10倍,甚至比纯手工制作的reducer还要快。
4。为什么需要Mutative?
手动编写immutable更新通常很困难,且易出错。Immer可以使用可变逻辑编写更简单的不可变更新。
但它的性能问题会导致运行时性能开销。Immer必须默认启用自动冻结(如果禁用自动冻结,性能会更差),Immer的这种不可变状态并不常见。跨进程、远程数据传输等场景不得不不断地冻结这些不可变数据。
Mutative还有很多的改进,比如更好的类型推断、非侵入式标记、支持更多类型的不变性、更安全等等。5。MutativevsImmer性能比较
测量(操作秒)以更新50K数组和1K对象为例,具体代码查看文末资料。NaivehandcraftedreducerNoFreezex3,713opssec0。86(89runssampled)MutativeNoFreezex5,323opssec1。69(93runssampled)ImmerNoFreezex8opssec0。88(23runssampled)MutativeFreezex875opssec1。20(95runssampled)ImmerFreezex320opssec0。45(92runssampled)MutativePatchesandNoFreezex752opssec0。16(96runssampled)ImmerPatchesandNoFreezex7opssec1。32(23runssampled)MutativePatchesandFreezex425opssec0。33(95runssampled)ImmerPatchesandFreezex239opssec0。99(89runssampled)ThefastestmethodisMutativeNoFreeze
运行yarnbenchmark。
操作系统:macOS12。6,CPU:AppleM1Max,Node。js:16。14。2
Immer依赖于自动冻结,如果禁用自动冻结,Immer将有巨大的性能下降,此时Mutative有巨大的性能领先。尤其是对于大型数据结构,Mutative将有超过50倍的性能领先。
因此,如果使用Immer,则必须启用自动冻结以提高性能。Mutative允许默认禁用自动冻结。使用两者的默认配置,可以看到Mutative(5,323opssec)和Immer(320opssec)之间明显的性能差距。
总体而言,Mutative在更多的性能测试场景中比Immer有巨大的性能领先。6。Mutative特点和优势Mutationmakesimmutableupdates支持打补丁(Supportapplypatches)可选冻结状态(Optionalfreezingstate)自定义浅拷贝(Customshallowcopy)不可变和可变数据可标记(Immutableandmutabledatamarkable)用于更安全的可变数据访问的严格模式(Safermutabledataaccessinstrictmode)支持JSON补丁(SupportforJSONpatches)支持reducer(Supportforreducer)7。Mutative和Immer之间的区别
差别可以通过下面的图进行说明:
Mutative和Immer之间的区别
除了上图的差异外,Mutative比Immer有更少的错误,经过混淆和Gzip压缩后,Mutative大小为4。16KB,而具有相同功能的Immer大小为4。67KB。
8。Mutative安装使用8。1安装yarninstallmutativenpminstallmutative8。2使用import{create}frommutative;constbaseState{foo:bar,list:〔{text:coding}〕,};baseState代表基础stateconststatecreate(baseState,(draft){draft。foofoobar;作为draf传递给第二个draf函数,修改后返回新的状态draft。list。push({text:learning});});9。本文总结
本文主要和大家介绍下Mutative和Immer,同时做了简单的对比。因为笔者也没有在生产项目中使用过Mutative和Immer,所以很多探索也就浅尝辄止,但是文末的参考资料提供了大量优秀文档以供学习,如果有兴趣可以自行阅读。
参考资料
https:blog。csdn。netJiaPeng366articledetails106455221
https:dev。tounadlibmutative10xfasterthanimmer2060
https:github。comunadlibmutativeblobmaintestperformancebenchmark。t
https:github。comunadlibmutative
https:immerjs。github。ioimmer
张国伟私接广告开除,如今自费复出引争议!凭什么郭晶晶全身而退2013年张国伟在全国室内田径锦标赛跳高决赛中,以2。32米的成绩夺冠,还打破了朱建华保持27年的室内赛跳高2。31米记录,一跃成为跳高项目的领头人。但谁也没想到的是他竟然被国……
乔任梁离开五年后一个失独家庭该如何生活下去?kimi乔任梁,一个阳光、帅气、爱笑的大男孩。2007年,20岁的他在选秀节目《加油!好男儿》中,荣获全国亚军,并因此出道。凡是看过乔任梁的节目和作品的观众,对他的……
每吨191亿元,嫦娥五号带回罕见物质,未来可成为人类新能源古时候由于人类的科技落后,人类一直都以为地球是唯一的世界,认为太阳和月亮都在围绕地球转动,后来随着人类科技的进步,人类走出地球之后才发现并不是这样的,地球是一颗行星,在太阳系中……
丁克39年的朱琳,她的结局早已注定文念维公子印象中的朱琳总是风轻云淡、柔情似水的样子,穿着西装、楚楚动人的上海知青叶娟;佩戴玉冠、柔情似水的女儿国国王;夹上工牌、妖娆妩媚的医生张洁。都说戏如人……
NBA球星花钱有多离谱?飞机豪宅只是皮毛,得知抚养费太离谱NBA作为世界篮球的天花板,聚集了世界上最好的篮球运动员,每个篮球运动员都将进入NBA作为自己的梦想,不仅是可以增加自己的名气,更能给自己带来不菲的收入。NBA球员的薪资吓人,……
辽宁首败杨鸣罕见暴怒,上海强力外援暂时离队,又有外援有意回归CBA新赛季第一阶段比赛激烈正酣,夺冠大热辽宁队爆冷输球,青岛、新疆同时遭到连败,但山西凭借着两连胜杀进了联盟前三。相信接下来的比赛将会更加激烈,积分榜的排名必定会产生令人意外……
韩国世界号火箭据韩国媒体报道,当地时间10月21日下午17时,韩国首枚自主研发的运载火箭世界号,在韩国的全罗南道罗老宇航中心发射升天,但是火箭没有将载荷送入预定轨道,此次韩国自主研发的运载火……
首次前往木星的任务可能揭示太阳系的起源,也给人类神话带来新解探索起源:露西与特洛伊2021年10月,美国宇航局(NASA)发射了一艘宇宙飞船,目的地是一组在木星附近围绕太阳运行的小行星。亚利桑那大学的行星科学家VishnuRedd……
克莱终于要复出了!我们熟悉的勇士回来了嘿,勇士国度,我就要复出啦!请对我保持耐心。顺带一提,这套黑色的队服设计得还是蛮好的嘛。这是阿汤今早在Ins上写下的一段话。看来阿汤是迫不及待的要跟勇士众将合体了。……
苦而不言,喜而不语很喜欢这句话:苦而不言,喜而不语,这个世界上很难有真正的感同身受,别人听你的遭遇,只是口头的附和,最多安慰几句,啊,他怎么这样,你也太善良了,太可怜了,诸如此类不痛不痒,无法改……
王者荣耀荣耀典藏皮肤推荐,这几款非常值得拥有!哈喽大家好,我是冲锋弟弟,众所周知,在王者荣耀中,皮肤等级大致分为四个档次,勇者、史诗、传说和荣耀典藏,等级越高皮肤越贵。今天弟弟就给大家推荐几款优先级最高的荣耀典藏皮肤。(以……
园来如此第七站,在岭南公园尽享岭南风光21座公园、131。5公顷总面积,近年来,静安区公园数量、面积、品质都有着显著提升。自2016年以来,静安绿化部门贯彻人民城市理念,结合城区绿化发展规划,加大公园建设力度,打造……