OC

flutter性能优化

Posted by sunzhongliang on March 2, 2023

const修饰的widget

对于一些不会改变的widget,flutter推荐我们使用const来修饰,这样在重绘界面时,会尽量复用已经存在的 element 节点
那么如果我们的 widget 被定义成 const,在 updateChild() 更新阶段,新旧 widget 就是同一个对象,则不会重建 widget,其背后的 elment 也不会更新,自然能起到了缓存复用的作用,加快构建的效率

控制build方法的耗时

  • 避免在 build() 方法中进行重复且耗时的工作,因为当父 widget 重建时,子 Wdiget 的 build() 方法会被频繁地调用
  • 避免在一个超长的 build() 方法中返回一个过于庞大的 widget。把它们分拆成不同的 widget,并进行封装

谨慎使用saveLayer

一些 Flutter 代码调用了性能代价很大的 saveLayer() 方法来实现 UI 中的各种视觉效果。你使用的其他 widget 或者 package 可能会在幕后调用它。也许你的应用程序会大量调用 saveLayer();过多调用 saveLayer() 会导致卡顿。

减少 saveLayer 的调用

调用 saveLayer() 会开辟一片离屏缓冲区并将内容绘制到离屏缓冲区可能会触发渲染目标切换。 GPU 希望直达目标地运行,但渲染目标迫使 GPU 暂时重定向到该数据流,然后又直接把它切回来。这样会对渲染吞吐量造成特别大的破坏性。

减少使用不透明度和裁剪

  • 能不用 Opacity widget,就尽量不要用。有关将透明度直接应用于图像的示例,请查看 Transparent image,这比使用 Opacity widget 更快。
  • 与其将简单的形状或文本包裹在一个 Opacity widget 中,不如用半透明的颜色来绘制它们会更快。(这仅在要画的形状中没有重叠的部分时有效)。
  • 要在图像中实现淡入淡出,请考虑使用 FadeInImage widget,该 widget 使用 GPU 的片段着色器应用渐变不透明度。
  • Clipping 不会调用 saveLayer() (除非明确使用 Clip.antiAliasWithSaveLayer),因此这些操作没有 Opacity 那么耗时,但仍然很耗时,所以请谨慎使用。
  • 要创建带圆角的矩形,而不是裁剪矩形来达到圆角的效果,请考虑使用很多 widget 都提供的 borderRadius 属性。

    懒加载列表

    构建一个大型网格列表或列表时,使用带有回调的懒惰构建器方法。这可以确保在启动时只构建屏幕的可见部分。

    减少由内部操作引起的布局传递

    Flutter 的基本布局规则: 首先,上层 widget 向下层 widget 传递约束条件; 然后,下层 widget 向上层 widget 传递大小信息; 最后,上层 widget 决定下层 widget 的位置

本文首次发布于 孙忠良 Blog, 作者 [@sunzhongliang] , 转载请保留原文链接.