构建更好、更廉价、更健壮的应用程序的最佳实践
Flutter 是 Google 开发的一个开源框架,它可能是当今最受欢迎的跨平台应用程序开发工具。它于 2017 年发布,从那时起,社区已经发展得如此之快,你可以通过谷歌找到足够的帮助。
自从我开始使用 Flutter 2.0 为 iOS 和 Android 开发应用程序以来,本文中的概念和技巧是我学到的一部分。然而,本文中的实践是为 Flutter 3 + 设计的(但它们也都适用于 Flutter 2 +)。
在 Flutter 中很容易混合关注点,因为逻辑层和表示层非常紧密,这使得代码更难长期维护,更容易出错,并且更容易重复自己。
然而,有多种技术可以用来分解关注点:
例如,不像下面这样管理条件语句:
生成方法中的三元运算符示例
做以下事情:
构建方法外部的三元运算符示例
widget 是 Flutter 的家务,它们是一切,而且所有的东西都是作为一个 widget 在引擎盖下工作的。这可能就是为什么在 Flutter 中开发这么容易的原因。
创建可重用的 widget 有两种方法:
一般来说,使用助手函数或类可以避免重复使用,并使代码看起来更干净、更容易维护,但是总是更愿意使用类来获得更好的性能(和可测试性)。
避免做以下事情:
使用 helper 方法构建返回卡的 widget
改为:
使用类构建返回卡的 widget
一个常见的好的和安全的假设是,在每一帧上,一个 Widget 都会调用 build 方法,这样 Flutter 就知道要渲染什么了。它通常不是那么关键(除非您的代码正在执行某些非常奇怪的操作) ,但是仍然经常调用构建方法,使得我们在方法中所做的任何事情都会被重新构建,除非被缓存。
大部分的 Widgets 已经被缓存了,但是业务逻辑、期货和繁重的任务将在 build 方法中再次执行,导致应用程序感到滞后和缓慢,因此损害了应用程序的用户体验。
解决这个问题的三个简单方法是:
FutureBuilder 是一个令人惊异的 widget ,它通过根据具体情况呈现特定的 widget 来显示未来的不同状态,如等待、成功和错误响应。可以这样使用(避免) :
每次执行构建方法时,FutureBuilder 都会调用 future
问题是 FutureBuilder 是一个 widget ,因此存在于构建方法中,正如前面解释的那样,在屏幕生命周期中多次调用构建方法,使它每次都能回想起未来。如果它是您的 API,那么它可能会增加服务器成本,或者它甚至可能是与端点的每次命中相关的成本的第三方 API。此外,它会使你的应用程序感觉更慢,用户体验会受到打击。
尽管如此,解决方案很简单: 您只需要在构建方法之外调用 future,并且只使用 FutureBuilder 检索内容。它仍然会有不同的状态,但未来只能解决一次。下一张图片是基于前一段代码的正确实现的示例:
FutureBuilder 只调用将来的结果,而不调用自己
有状态 widget 有一个非常棒的方法来告诉 widget 代码中的某些内容已经发生了变化,需要重新构建自己; 这就是 setState() 方法。
如果你想修改一个变量并且让 UI 知道这个变化,你必须在 setState 内部进行,但是,因为它负责告诉 widget 重新构建自己,它应该只有所需的变化,否则 UI 会变得迟缓和缓慢(特别是因为 setState 是一个同步方法)。
这里的最佳实践是避免在对 setState() 的调用中使用繁重的逻辑,而是在外部进行繁重的提升,并且只指示通过 setState() 在 UI 中显示的确切更改。例如:
SetState 方法使用的不好和好的例子
来自 web 开发的开发人员倾向于在 Flutter 使用 container widget ,就像他们在 HTML 中使用 div 一样。我在这里告诉你: 停止这样做。 container 需要很多东西才能在引擎盖下工作,它们很重,如果你只是用它们来包装其他 widget ,它们很容易降低 FPS 并使应用程序滞后。不要误解我的意思,它们经常被需要,而且它们的存在是有原因的,但是,这里的想法是只在你真正需要它们的时候使用它们,因为在 container 中包装一个没有其他参数设置的 widget 没有任何效果,并且使代码变得不必要的复杂。
此外,当您认为需要一个 Container 时,首先查找 Widget Catalog,看看是否有另一个 Widget 已经满足您的需要。你可能会对 Flutter 已经建成的东西感到惊讶。
第一个示例,在不需要时使用 Container:
不需要 container 时使用 container
第二个例子,当有另一个 widget 效率更高时使用 Container:
当 SizedBox 更有效时使用 container
Dart 允许我们使用 var 声明动态数据类型,因为动态数据类型负责这些值; 当您不知道所拥有的变量的数据类型时(通常是从 API 获取数据时) ,这很有用。但是,动态数据类型可能成为一个健壮的噩梦,使您的代码更容易出现运行时错误,同时使用适当的数据类型,您可以从编译器获得帮助,可能还可以从 IDE 获得帮助。
我对此的一点建议是避免使用动态数据类型和 var 声明,强迫自己理解数据的含义,如果可以选择不放置类型,那么还是放置它。
对于最后一条建议,一个特别有用的例子是在使用 FutureBuilder 和 AsyncSnapshot 时不使用类型:
IDE 和编译器都不知道快照要检索什么数据,这是导致运行时错误的一个常见原因。但是,如果您添加数据类型,他们可以在编译时知道并通知您错误:
正如我们所看到的,快照所期望的数据类型是一个 String,它甚至抛出了一个错误,因为将来不会返回一个 String。这个简单的红色高光可能是长夜和短夜的区别。始终使用数据类型!
请继续关注更多这样的文章。如果你想让我写一些东西,特别是,让我知道在评论。
我是一个爱好学习的人,所以我很乐意阅读你们的意见和任何反馈,继续我的学习之路,请去留言!
感谢您阅读这篇文章,让我们一起创造一个更美好的世界吧! 弃
如果你喜欢的话,可以关注更多并分享它
如果本文对你有帮助,请转发让更多的朋友阅读。
也许这个操作只要你 3 秒钟,对我来说是一个激励,感谢。
祝你有一个美好的一天~
© 猫哥
微信 ducafecat
https://wiki.ducafecat.tech
https://video.ducafecat.tech
本文由 mdnice 多平台发布