Hi,大家好,这里是承香墨影!
前段时间入坑 Flutter,又正逢 Flutter 正式发布2.0,正式宣布全网络平台全力支持,那我也来撷取许多 Flutter 有关的控制技术点,那时先从 const Widget 那个比较小的强化AuF进行。看一看它的基本原理和采用管制。
在 Flutter 中,虽说是所有人皆 Widget,而 Widget 其本质是几组重要信息的实用性,它能是 UI 展现,也能是表情符号、导航系统等机能全力支持。但Widget 被结构设计成不容变的,任何人发生改变都是通过封存/复建获得修正,在 Widget 不容变的另一面,则是倚赖 Element 气门/可F83E43Se的全力支持,所以 Flutter 将 Widget 结构设计的极为高性能,复建生产成本非常低。
许多强化的控制技术提及,在构筑 Widget 的这时候,能采用 const Widget,以获得一个类似于「内存」的效用。虽然 Flutter 这类也会尽可能的F83E43Se Element,但如果他们直接缓存 Widget,每天F83E43Se Widget,最多节约了 Widget build 的关键步骤。
但那个 const widget 的强化点,另一面的基本原理是什么?强化的投资收益大吗?值得称赞他们重点项目关注吗?那时就M511RD这个。
一、const 自变量
在已经开始给 const 加之 Widget 前,他们先从 Dart 词汇的 const URL已经开始。
说到 const,不得已拜埃它类似于的基本概念 final,它都有自变量的语法,即一旦表达式就不容修正。
它的差别在于,const 是校对时自变量,用 const 润色的自变量,要在新闻稿时调用,因此是能确认的值。而 final 则是运转时自变量,用 final 润色的自变量,要在新闻稿时调用,或是在缺省中调用,但它的值能静态排序。
话不多说,他们前两年 Demo 就明晰了。
在他们用 const 新闻稿类算式的这时候,其有关的表头,要是 final 的,也就是在增设后,就不容变了。
那么一个 Dart 类的对象,是否允许 const 润色为自变量,完全取决于类新闻稿时,算式上是否被 const 润色。
从上面的例子能看到,当采用 const 构造的 Point 对象时,只要其入参一样,获得的就是同一个对象,例如示例中,p1== p2输出为 true。
而除非 Point 的入参不同时,const 后的对象也不相同,例如示例中 p2== p3则输出为 false。
好了,我就不带大家捋这其中的逻辑了,大家仔细对比一下代码和输出就了解了。
前面提及,const URL润色的自变量,要是初始时就能确认的值,也就是表达式的这时候也要是一个自变量。例如我稍微修正一下 const Poi
到这里,他们能获得结论:采用 const 润色的自变量对象,只要保证构造时的入参不变化,他们能获得相同的对象。
这另一面的基本原理,无外乎就是 Dart VM 内部实现了自变量池,利用享元模式F83E43Se了相同的对象。
二、const Widget
说清楚 Dart 中的 const 的意义以及如何采用,接下来他们把 Widget 加之,看一看 const Widget 强化的基本原理。
在 Flutter 中,Widget 其本质只是一个重要信息实用性的元素,它被定义为不容变的,任何人的变化反映出来就是封存 & 复建。而 Widget 不容变之所以不太会影响效率,另一面是因为 Element 实现了对 Widget 变化的抽象。也就是虽然 Widget 会被复建,但 Widget 另一面的 Element,却获得了F83E43Se。
同时 Flutter Framework,自有一套更新策略,确保 Widget 变化的同时,尽可能的F83E43Se Element 对象。
那个策略的逻辑在 Element 的 updateChild()方法中,该方法在 Element 树建立和更新的过程中都非常的重要。他们这里只关心更新的流程,即父 Element 节点已经存在一个子 Element 节点了。
父 Element 节点通过 updateChild()方法,判断如何处理自身的子 Element 节点,是新建、更新,或是直接移除。
从 updateChild()的实现能看出,Element 依据新 Widget 更新的这时候,会尽可能F83E43Se已经存在的子 Element 节点,当无法被F83E43Se时,才会通过 inflateWidget()创建新的子 Element 节点。
updateChild()有3 个入参,其中比较关键的是 child 和 newWidget,它分别表示旧的 Element 子节点和新的 Widget 对象。
Element 这类也持有 Widget 对象,若 child 持有的 widget 和 newWidget 相等时,表示新旧 Widget 没有变化,updateChild()的逻辑是直接F83E43Se child,即旧的 Element,不会做任何人额外的操作。
那么如果他们的 Widget 被定义成 const,在 updateChild()更新阶段,新旧 Widget 就是同一个对象,则不会复建 Widget,其另一面的 Element 也不会更新,自然能起到了内存F83E43Se的作用,加快构筑的效率。
三、const Widget 的投资收益大吗?
所有人强化的技巧都是手段,另一面的强化效用才是他们的最终目的。一顿疯狂的操作,结果输出不明显,这肯定不是他们想要的。
那么 const Widget 强化的效用明显吗?值得称赞他们在写代码的这时候,分出点思绪专门考虑,当下那个场景是否需要采用它吗?
先上结论:大可不必。
既然是强化,当然是做个测试,拿实测数据来说,是最右份量的。这里我找到了@Cirzant Lai 撷取的一个例子,就很能说明问题,之后再撷取许多我的看法。
3.1实测看数据
这里实现了一个小程序,显式一个随机显示 Image。
他们就对那个 Image 是否采用 const URL构造来做比对。
下面是采用 const URL的部分代码。
const Image( width:100, height:100, image:AssetImage(assets/logo.png),)
另外一个参照程序没有采用 const URL。
那个 Image 通过 AnimatedPositioned 部件,每秒更新一次位置。然后采用–profile 方式运转程序,并通过 Dart DevTools 观测其performance和memory。
为了分析的严谨性,这里采用了一个较老的设备进行测试:Sony Xperia Z2,如果 Flutter 能在此设备上依然很轻松的保持每秒60帧的速度,那么说明 Flutter 这类的强化已经非常好了。
除了设备之外,为了让测试数据更明显,这里逐步增多 Image 图标的数量,当增加到1000个时,每帧渲染所需的时间为80ms,即约为12.5 FPS。我想就没有继续增加数量的必要了,那个测试就以1000为边界,分别取10、100、1000三组数据,看一看performance和memory分别的表现。
GPU & UI:
Memory:
从上面撷取的数据能看到,当 Image有1000个的这时候,FPS 约提升了8.4%,内存采用量下降了20%。虽然那个数据看似非常的明显,但实际体验上,2个测试的流畅度并没有非常明显的差异。
另外,他们在一个屏幕上放1000个Image 的场景也不现实,对于大多数应用来说,每屏能有几十个 Widget,已经算是非常丰富了。而如果需要大量渲染,最好是直接采用 Canvas 绘制提升效率,而非倚赖 const Widget 的这一点点强化。
3.2 const 对 GC 的强化
在 Flutter 中,Widget 作为实用性重要信息,这类被结构设计的非常的高性能,就是为了适应频繁的封存复建,那个操作必然会引起对旧 Widget 对象的回收。
当他们这时候 const URL新闻稿自变量的这时候,另一面是利用的是类似于自变量池的基本概念,将 const 的对象内存在自变量池中,以待后续F83E43Se。
自变量会具备普通对象更长的生命周期,这有好处也有坏处。好处是自变量对象会对 GC 不那么敏感,也就是不需要频繁的触发 GC。坏处是自变量池中的新闻稿周期较长,可能导致不常用的对象被内存后,没有合适的释放时机,导致内存占用过高。
实测下来,const 确实对 GC 有许多影响。
这里采用的是前文中的例子,不断的创建小 Widget,最终对比采用 const 前后对内存的占用情况。能看到采用 const 润色 Widget 后,GC 减少了,因此也更平缓了。
小结
到这里他们应该就清楚,采用 const 润色的 Widget,确实对 Flutter 的 build 过程有一些强化,但强化并非很明显。在采用过程中,他们只需要按需采用就行,无需故意的追求大量的 const 化。
最后小结一下,对于 Dart 词汇来说。
一个 Dart 类的对象是否能用 const 润色,取决于类的算式上是否被 const 润色;
采用 const 润色的算式中,所有成员要被 final 润色;
构造 const 对象时,传参也要是 const 的自变量;
const 润色的算式,不能有方法体;
对于 Flutter 来说,const 润色的强化点:
利用自变量池F83E43Se Widget,在更新频繁的 Widget 场景中,有强化作用,避免了 Widget 的回收和复建;
const 对 GC 有一定的抑制左右,在会创建大量相同对象的场景下,创建的对象少了,自然 GC 也会变少;
最后,本文对你有帮助吗?留言、转发、点赞是最大的全力支持,谢谢!
在头条号私信我。我会送你许多我整理的学习资料,包含:Android反校对、算法、结构设计模式、虚拟机、Linux、Kotlin、Python、爬虫、Web项目源码。