Flutter性能优化实践 2023-08-31 周四

2023-08-30  本文已影响0人  松哥888

简介

APP匆忙上线之后,就提出了性能优化的需求。
一路走来,还是有了一点点进步。

图片

性能优化,图片是绕不开的话题。
图片分为本地图片和网络图片两种。
一般本地图片不存在性能问题,而网络图片存在性能和体验等方面的制约。

图片组件

image.png

网络图片

使用历史

企业微信截图_8f7f4de3-0540-4441-bc19-e4d9173f7da2.png

参考文章: Flutter - 加载网络图片的几种方式

缩略图

阿里CDN服务器提供缩略图服务,网络图片尺寸变小,流量节省,性能也会提升。当然,相应的,图片清晰度会下降,体验会降低。这个就需要一个平衡。
我们的首页图片非常多,就用到了这个服务。用起来也非常简单,按照规则,修改图片的url就可以了。

/// 拼接参数,进行图片缩放
/// w和h要一样大
/// w和h要整数
/// w和h只能整10和整100
/// w和h不能根据屏幕自适应(不能保证整10整100)
/// 目前只有alicdn才能这么做;比如微店的geilicdn就不行
String url = item['goodsImg'] ?? '';
if (url.contains('alicdn')) {
  int w = 400;
  int h = 400;
  url = '${url}_${w}x$h.jpg';
}

缓存管理

class CustomCacheManager {
  static const key = 'image_cache_key';
  static CacheManager instance = CacheManager(
    Config(
      key,
      stalePeriod: const Duration(days: 7),
      maxNrOfCacheObjects: 100,
    ),
  );

  /// 首页购物时报采用单独的缓存
  static const homeRealTimeKey = 'homeRealTimeKey';
  static CacheManager homeRealTimeInstance = CacheManager(
    Config(
      homeRealTimeKey,
      stalePeriod: const Duration(hours: 2),
      maxNrOfCacheObjects: 200,
    ),
  );

  /// 首页购物时报采用单独的缓存
  static const goodsDetailKey = 'goodsDetailKey';
  static CacheManager goodsDetailInstance = CacheManager(
    Config(
      goodsDetailKey,
      stalePeriod: const Duration(hours: 2),
      maxNrOfCacheObjects: 200,
    ),
  );
}

sliver家族

ListView嵌套

ListView(
  shrinkWrap: true,
  physics: const NeverScrollableScrollPhysics(),
  children: pis.map((e) => _piCell(get, e)).toList(),
)
Column(
  children: pis.map((e) => _piCell(get, e)).toList(),
)

Raster

image.png

这里的意思是默认三个钩都打上,也就是3个方面都检测。然后一个一个去掉,看性能是否有改善。这样就能反推出影响性能的到底是Clip, Opacity,shadows中的哪一个。

耗时函数

企业微信截图_591e924f-a5ff-414c-973e-cc12eeebe594.png 企业微信截图_5cf99c76-b7fe-4aa2-bfd8-0604948cde22.png 企业微信截图_a355e5fd-ef69-4bfb-8a45-b6d077b24e39.png 企业微信截图_038a7af8-b987-42d9-9e92-b023d8204115.png
@override
  Map<String, Color?> get lightInfo => {
        PandaColorSring.coltheme: const Color(0xff2865ff),
        PandaColorSring.colffffff: const Color(0xffffffff),
        PandaColorSring.col000000: const Color(0xff000000),
// ... ...
}

这只是一个数组,存放了所有light模式下的颜色。对应的,还有darkInfo,存放了所有dark模式下的颜色定义。

@override
  Map<String, Color?> lightInfo = {
        PandaColorSring.coltheme: const Color(0xff2865ff),
        PandaColorSring.colffffff: const Color(0xffffffff),
        PandaColorSring.col000000: const Color(0xff000000),
// ... ...
}

这样改会有警告,集成重写,需要get关键字。所以可以考虑去掉继承,重新整理一下。

暗黑模式检查

Get.isDarkMode
  /// 记忆状态,默认不是暗黑模式
  static bool isDarkMode = false;

  /// 在需要的时候检查状态,更新静态变量
  static checkDarkMode() {
    String type = LocalStorageUtil.getThemeType();
    if (type == 'auto') {
      isDarkMode =
          (MediaQuery.of(Get.context!).platformBrightness == Brightness.dark);
    } else {
      isDarkMode = Get.isDarkMode;
    }
  }

  /// 对外接口,直接返回静态变量,提升性能
  static bool isdark() {
    return isDarkMode;
  }
  static updateTheme() {
    /// 这里需要delay,不能直接调用Get.forceAppUpdate();
    Future.delayed(const Duration(milliseconds: 200), (() {
      Get.forceAppUpdate();

      /// 状态更新后,检查模式,更新静态变量
      checkDarkMode();
    }));
  }

性能分析

image.png
上一篇 下一篇

猜你喜欢

热点阅读