Skip to content

[perf] 输入场景下的页面性能优化 #105

@hazuki-keatsu

Description

@hazuki-keatsu

现象

输入法弹出时页面卡顿

Flutter DevTools中的截图:

  1. 输入法弹出
Image
  1. 屏幕旋转
Image

原因

在每次MediaQuery改变时,所有监听MediaQueryWidget都会重建,而本项目的i18n方案使用的是flutter_i18n,并且是在build()中直接使用FlutterI18n.translate()来进行对应资源的查询,意味着每次MediaQuery的变化都会从i18n文件中加载所有的i18n资源,进而带来大量的文件io性能消耗,这是XDYou在弹出输入法时卡顿的原因。

可能的解决方法

  1. 使用Flutter官方推荐的Intl包,但是这个项目已经大量使用flutter_i18n,故不推荐。
  2. 将部分页面的i18n字符串存进组件状态,由组件自行管理,在合适的时候(didChangeDependencies())进行更新,这个方法推荐。
  3. 拓展目前项目的另一套国际化方案NonUII18nnon_ui_i18n,这个国际化方案是我在写通知系统的时候顺手写的,用来解决在repository层的国际化。由于抛弃了对BuildContext的依赖,所以需要开发者自行使用地区代码查询。目前该组件只是能用的状态,可以拓展功能以面对不同场景的使用。这个方法同样面临大量的代码重构,所以不予优先推荐。

FlutterI18n 自己的设计问题

在FlutterI18n的代码中:

// lib/loaders/file_translation_loader.dart 第 63-66 行
@override
Future<String> loadString(final String fileName, final String extension) {
  return assetBundle.loadString('$basePath/$fileName.$extension',
      cache: false);  // ← 这里明确设置了 cache: false
}

作者明确禁用了缓存机制,作者可能考虑到热重载场景,希望翻译文件修改后立即生效,但是这个设计在该项目中的性能问题被大幅放大。对于XDYou来说,这个问题可能是一个需要长期去解决的问题。


为什么我不写?

因为我最近很忙,快期末了,要准备考试,看看有没有大手子来解决一下。就先发个 Issue 说明一下问题。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions