昨晚把React
的官方入门Demo敲了一遍,感觉对声明式的框架 React,Flutter,Android-Compose
都有了一些认知,故想记录下。
我开始学习的是Flutter,看了文档,敲Demo,对比Android原生开发的一些熟悉概念,后面看到Android也推出了Compose,又跑去玩玩Compose, 发现两个框架都在”抄” React,忍不住去认认这”祖师爷”,通过不同框架对同一概念的实现,从而加深对声明式框架的理解。
前端,主要干的活,定义如何展示数据,处理数据和视图的关系,处理事件到来后数据变化,重新渲染数据成视图。
其中,由于数据在视图中是变化的,故,我们将之称为状态state,而对于一部分数据对本视图而言,它是不可变的,我们称之为属性props,要注意的 是这里的可变或不可变是对于本视图而言的,一般,父亲的state对孩子的来说就是props。 而,事件通常分为用户产生,如触摸事件,和系统产生,如时钟滴答导致状态进入下一个生命周期,我们称之为动作action。
1 | model = props + state // 数据由不变的属性和可变状态组成 |
此后便是声明式和传统的开发的区分
传统的方法
1 | action(model) >> diff // 事件过来进行处理,产生一些变化diff |
存在的问题是,我们渲染数据的逻辑变得很复杂,为何?一个事件,产生一个变化diff,需要对这个diff添加新的渲染代码,即随着事件的远远不断地到来, 我们要不断地维护更新这个视图树,随着事件变多,往往会出现,model和view不同步的情况,因为我们在修改model的同时,也要同时修改view。
而声明式的方法是
1 | action(model) >> new_model // 事件过来产生一个新的model |
这样,当定义好一个渲染逻辑后,只要model的结构不变,我们就可以不用改变原来的render方法,从而保持渲染逻辑的简单。
以上,是对声明式框架的理解,以下做一些额外的思考。
若论性能而言,传统开发更优,但是声明式开发模式更注重开发效率和代码维护性。 以此,声明式开发是未来的一种趋势。
传统方式,直接修改原来数据,然后视图同步数据的修改,而声明式开发,复制了全部的数据,修改数据后交给视图一个全新的数据镜像重新渲染。 根据这点,声明式要使用更多的内存和更频繁的对象销毁回收,因此在利用计算机性能上效率低。但,从历史趋势的趋势上声明式开发是未来,一方面, 计算性能在增加,另一方面,降低编程心智负担一直我们追求的目标;这个论证过程也可从编程语言的发展史得到印证。
而在框架的具体实现上,性能上也做了很多优化。Flutter,从用户描述到渲染经过了 widget > element > renderObject的过程, widget是我们对一个组件的最简单的描述定义,element表示了其组件的关系树,而renderObject才是真正用于渲染的视图树。 其作用是,导致widget对象都很小,回收成本低,而真正的渲染树,在widget修改时,对应渲染树只是增量更新,而不是和widget一样全量更新。