likes
comments
collection
share

【小声团队】Flutter Desktop 实战 - 渲染怎么做到丝般顺滑?

作者站长头像
站长
· 阅读数 18

本文由小声团队出品,小声团队是一个专注于音频&音乐技术的初创团队,深度使用Flutter构建跨平台应用,希望与大家一起共同探索Flutter在桌面端&移动端的可能性。

背景

作为一个工具厂商,有相当多的功能都依赖于用户的实时UI操作,比如PhotoShop,界面总是在毫秒级别发生不停的变化,同时又仍然继续响应用户的鼠标操作,键盘输入等。 比如我们可以看到一个典型的如下案例

【小声团队】Flutter Desktop 实战 - 渲染怎么做到丝般顺滑?

我们可以看到界面需要实时的响应用户的输入,同时又需要进行大量的数据处理,这些数据处理可能是高CPU的或者高延迟的。如果我们将数据处理与UI渲染同步完成,那么势必会阻塞线程,从而造成UI卡顿的现象,那么我们从优化的角度怎么来思考这个问题嘞?

我们都知道,优化大体上分为几种:

  • 算法优化。比如将算法时间复杂度从O(N) 提升到O(1),或者将O(n2)提升到Olog(n)。
  • 流程优化。合理的安排程序处理的流程,将宝贵的CPU时间尽可能的放在庚戌要及时反馈的地方。

这里我们不从算法角度来分析,我们仅仅从业务流程上来看应该怎么处理。

优化前的思考

在拿到一个渲染优化的任务之后,我们可以先问自己几个问题。

用户输入的处理需要实时吗?

假设我们正在制作一个音频变速器。用户通过上面截图的类似方式进行操作,那么我们真的需要每次用户滑动就去处理数据吗?

在哪里处理数据的变更更合适?

如果我们可以不实时处理数据,那么我们应该如何处理,我们的实践经验来说,分为两种做法。

  • 定时批处理,将数据变更的请求做成队列,开启后台线程批处理。
  • 用户一次操作结束之后再处理,比如一次完整的鼠标操作事件为 MouseDown -> MouseMove -> MouseUp,那么我们可以在MouseDown的时候记录任务开始,MouseMove的时候仅仅做UI数据变动,并且将数据缓存,最后在MouseUp发生的时候一次性提交。这样没有必要开启额外的线程,同时在用户高频的MouseMove事件中工作是非常轻量的,而在MouseUp之后用户操作也就是停止了,同时也就意味着界面的高频刷新停止了,此时将处理任务延到这个阶段,虽然仍然是单线程,但是却是合理的利用流程优化来分担CPU时间。

#总结 优化有的时候是带有副作用的,比如我们采用延迟变更的做法来保证渲染质量,那么也就意味着数据变更的优先级倍人为滞后,此时我们就要分析这样的副作用是否可以被接收。

转载自:https://juejin.cn/post/7044189972798111775
评论
请登录