Flutter 图片选择器性能优化实践

20 篇文章 2 订阅

Flutter 图片选择器性能优化

##:使用Flutter实现了一个图片选择器控件,集成到Hilight里面。 自测发现在一些低端机上会有卡顿现象,需要优化下才能提测

git项目地址

ui截图

优化项目:

1. 局部刷新

最先想到的是这个,每次数据变动只刷新对应变动的UI,避免直接用 setState 全屏刷新。具体是实现是:

  • 尽可能使用const。 使用const的 对象只会实例一次
  • 把 build方法抽取出 独立控件,构造函数 尽量设置成const.
  • 使用ValueNotifier 来实现局部刷新。比对了几种状态管理的模型,觉得这个地方ValueNotifier会比较合适
//初始化包装:
  ValueNotifier<int> segmentValue = ValueNotifier(0);
//数据更改:
    segmentValue.value = value;

//触发UI刷新:
      child: ValueListenableBuilder(
        valueListenable: segmentValue,
        builder: (context, value, child) {
          return Stack(
            alignment: Alignment.topCenter,
            children: <Widget>[
              Center(
                child: _segment(),
              ),
              Positioned(
                top: 16,
                child: btnClose(),
                right: 16,
              )
            ],
          );
        },
      ),

2. 分页优化

  • 修改分页触发时机,提前点加载。
scroll.metrics.pixels / scroll.metrics.maxScrollExtent > 0.7
  • 只接收ScrollEndNotification事件,来实现 滑动停止时加载
 return NotificationListener<ScrollEndNotification>(
      onNotification: (ScrollEndNotification scroll) {
        _handleScrollEvent(scroll);
        return true;
      },
  • 避免 notification 通知重复触发,引入loading来判断,如果正在请求分页,不重复请求
  _handleScrollEvent(ScrollNotification scroll) {
    if (scroll.metrics.pixels / scroll.metrics.maxScrollExtent > 0.7) {
      if (!isEnd && !loading) {
        _fetchNewMedia(pathEntity);
      }
    }
  }

    _fetchNewMedia(AssetPathEntity pathEntity) async {
    loading = true;
    List<AssetEntity> media =
        await pathEntity.getAssetListPaged(currentPage, 60);

    if (media.isEmpty) {
      isEnd = true;
      return;
    } else {
      setState(() {
        _mediaList.addAll(media);
        currentPage++;
        loading = false;
      });
    }
  }

完整的例子可以参考: git地址

内存优化

  • 由于messageChannel会被频繁调用,因此native那边需要设置一个线程池来缓冲请求。
  • flutter 实现LRU 缓存功能,使用内存缓存已经获取的图片,加快图片显示速度
  • 根据产品UI,确定要加载的图片宽高,来加载图片。
//默认GridView小图的宽: 
MediaQuery.of(context).size.width / (3 * 2);

//预览图的宽: 
MediaQuery.of(context).size.width 

页面初始化优化

  • 尽量在 widget的 initState里面 请求数据,避免build里面重复请求
  • 把FutureBuild的初始化放在 initState里面,设置为成员变量,减少重复调用
  Future<AssetPathEntity> recentFolder;

  @override
  void initState() {
    super.initState();
    recentFolder = getRecentFolder();
  }

参考

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值